diff --git a/packages/chainlink/docker/jobs_creator/templates/nba-create.json b/packages/chainlink/docker/jobs_creator/templates/nba-create.json new file mode 100644 index 000000000..bbc7755cd --- /dev/null +++ b/packages/chainlink/docker/jobs_creator/templates/nba-create.json @@ -0,0 +1,24 @@ +{ + "name": "Augur | NBA Market Creation - ${NBA_MARKET_FACTORY}", + "initiators": [ + { + "type": "web" + } + ], + "tasks": [ + { + "type": "augur-adapter", + "params": { + "sport": "nba", + "method": "create", + "startBuffer": 86400, + "affiliateIds": [ + 9, + 3 + ], + "daysInAdvance": 7, + "contractAddress": "${NBA_MARKET_FACTORY}" + } + } + ] +} diff --git a/packages/chainlink/docker/jobs_creator/templates/nba-resolve.json b/packages/chainlink/docker/jobs_creator/templates/nba-resolve.json new file mode 100644 index 000000000..154273515 --- /dev/null +++ b/packages/chainlink/docker/jobs_creator/templates/nba-resolve.json @@ -0,0 +1,24 @@ +{ + "name": "Augur | NBA Market Resolution - ${NBA_MARKET_FACTORY}", + "initiators": [ + { + "type": "web" + } + ], + "tasks": [ + { + "type": "augur-adapter", + "params": { + "sport": "nba", + "method": "resolve", + "startBuffer": 86400, + "affiliateIds": [ + 9, + 3 + ], + "daysInAdvance": 7, + "contractAddress": "${NBA_MARKET_FACTORY}" + } + } + ] +} diff --git a/packages/smart/addresses.ts b/packages/smart/addresses.ts index addf4d5ee..d5c75fb16 100644 --- a/packages/smart/addresses.ts +++ b/packages/smart/addresses.ts @@ -1,5 +1,6 @@ // This file is updated by deployer. import { AddressMapping } from "./constants"; + export const addresses: AddressMapping = { 31337: { reputationToken: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", @@ -52,150 +53,210 @@ export const addresses: AddressMapping = { ], info: { uploadBlockNumber: 1, graphName: "" }, }, - 80001: { - reputationToken: "0x1A921b8a13372Cc81A415d02627756b5418a71c9", - balancerFactory: "0xE152327f9700F1733d12e7a507045FB4A4606C6F", + 137: { + reputationToken: "0x435C88888388D73BD97dab3B3EE1773B084E0cdd", + balancerFactory: "0x3eC09e2A4699951179B61c03434636746aBE61AA", marketFactories: [ { type: "MLB", subtype: "V3", - address: "0x930fdaC8CBeC4279401a2bf864eeeaa85c00123D", - collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", - ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", + address: "0x03810440953e2BCd2F17a63706a4C8325e0aBf94", + collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", + fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", hasRewards: true, - masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", + masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", description: "mlb", - version: "FILL THIS OUT", + version: "v1.4.0", }, { type: "NBA", subtype: "V3", - address: "0x9A45627C8479D8dA6F270067C5451BcdaC477Aa0", + address: "0xe696B8fa35e487c3A02c2444777c7a2EF6cd0297", + collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", + fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + hasRewards: true, + masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + description: "nba", + version: "1.4.0", + }, + { + type: "NFL", + subtype: "V3", + address: "0x1f3eF7cA2b2ca07a397e7BC1bEb8c3cffc57E95a", + collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", + fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + hasRewards: true, + masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + description: "nfl", + version: "1.4.0", + }, + { + type: "MMA", + subtype: "V3", + address: "0x6D2e53d53aEc521dec3d53C533E6c6E60444c655", + collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", + fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + hasRewards: true, + masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + description: "mma/ufc", + version: "1.4.0", + }, + { + type: "Crypto", + subtype: "V3", + address: "0x48725baC1C27C2DaF5eD7Df22D6A9d781053Fec1", + collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", + fetcher: "0x0C68954eCB79C80868cd34aE12e0C2cC8E1Cc430", + hasRewards: true, + masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + description: "crypto prices", + version: "1.4.0", + }, + ], + info: { uploadBlockNumber: 15336699, graphName: "matic" }, + }, + 80001: { + reputationToken: "0x1A921b8a13372Cc81A415d02627756b5418a71c9", + balancerFactory: "0xE152327f9700F1733d12e7a507045FB4A4606C6F", + marketFactories: [ + { + type: "Grouped", + subtype: "V3", + address: "0xC844a28C66E0796321351a262cB87A5da5D3d8fa", collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", + fetcher: "0xDB1FDD47b2dDc7d98698e8248202A56FCB7De53B", hasRewards: true, masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", - description: "nba", + description: "grouped", version: "FILL THIS OUT", }, { - type: "NFL", + type: "MLB", subtype: "V3", - address: "0x51266210260d7d68Defdbf0D7D52378B66807570", + address: "0xaa7156a7B4d9590220D59e219B900FfDa52F6153", collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", + fetcher: "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", hasRewards: true, masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", - description: "nfl", + description: "mlb", version: "FILL THIS OUT", }, { - type: "MMA", + type: "NBA", subtype: "V3", - address: "0xEB9FfEd2fef65576577cD88d62E557e364225a1f", + address: "0xedf8f21CD357Fb3B51dfc9bAc227a678344956CE", collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", + fetcher: "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", hasRewards: true, masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", - description: "mma/ufc", + description: "nba", version: "FILL THIS OUT", }, { - type: "Grouped", + type: "NFL", subtype: "V3", - address: "0xCd5b1d5EB5944dC7497dC37f68E406f3A5aB4178", + address: "0xaf2ed373E031bA5c9Ad10E4686e1F5C1074639D2", collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0xEBC839dA45b1045bE3b02912714d55F592575157", + fetcher: "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", hasRewards: true, masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", - description: "grouped", + description: "nfl", version: "FILL THIS OUT", }, { - type: "CryptoCurrency", + type: "MMA", subtype: "V3", - address: "0x6B12716B875320Dd7c6fC1161639f93a088091B7", + address: "0x9213E2Ce5D0Eb030Aaccce61685e0453a8426947", collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", - fetcher: "0x4D32E966a79bFB049Fc48655e6Ae8785ed34e44f", + fetcher: "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", hasRewards: true, masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", - description: "crypto prices", + description: "mma/ufc", version: "FILL THIS OUT", }, - ], - info: { uploadBlockNumber: 15336699, graphName: "mumbai" }, - }, - 137: { - reputationToken: "0x435C88888388D73BD97dab3B3EE1773B084E0cdd", - balancerFactory: "0x3eC09e2A4699951179B61c03434636746aBE61AA", - marketFactories: [ { type: "MLB", subtype: "V3", - address: "0x03810440953e2BCd2F17a63706a4C8325e0aBf94", - collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", - fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + address: "0x930fdaC8CBeC4279401a2bf864eeeaa85c00123D", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", hasRewards: true, - masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", description: "mlb", - version: "v1.4.0", + version: "FILL THIS OUT", }, { type: "NBA", subtype: "V3", - address: "0xe696B8fa35e487c3A02c2444777c7a2EF6cd0297", - collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", - fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + address: "0x9A45627C8479D8dA6F270067C5451BcdaC477Aa0", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", hasRewards: true, - masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", description: "nba", - version: "1.4.0", + version: "FILL THIS OUT", }, { type: "NFL", subtype: "V3", - address: "0x1f3eF7cA2b2ca07a397e7BC1bEb8c3cffc57E95a", - collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", - fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + address: "0x51266210260d7d68Defdbf0D7D52378B66807570", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", hasRewards: true, - masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", description: "nfl", - version: "1.4.0", + version: "FILL THIS OUT", }, { type: "MMA", subtype: "V3", - address: "0x6D2e53d53aEc521dec3d53C533E6c6E60444c655", - collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", - fetcher: "0xcfcF4EF9A35460345D6efC7D01993644Dbcd4273", + address: "0xEB9FfEd2fef65576577cD88d62E557e364225a1f", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", hasRewards: true, - masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", description: "mma/ufc", - version: "1.4.0", + version: "FILL THIS OUT", }, { - type: "Crypto", + type: "Grouped", subtype: "V3", - address: "0x48725baC1C27C2DaF5eD7Df22D6A9d781053Fec1", - collateral: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", - ammFactory: "0x79C3CF0553B6852890E8BA58878a5bCa8b06d90C", - fetcher: "0x0C68954eCB79C80868cd34aE12e0C2cC8E1Cc430", + address: "0xCd5b1d5EB5944dC7497dC37f68E406f3A5aB4178", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0xEBC839dA45b1045bE3b02912714d55F592575157", hasRewards: true, - masterChef: "0x1486AE5344C0239d5Ec6198047a33454c25E1ffD", + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", + description: "grouped", + version: "FILL THIS OUT", + }, + { + type: "CryptoCurrency", + subtype: "V3", + address: "0x6B12716B875320Dd7c6fC1161639f93a088091B7", + collateral: "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", + ammFactory: "0xDcf4173FC3947bC2CbAB929559b7f38Cb25Bef34", + fetcher: "0xdA65A1f9c322384F743C474040283897cDcE8cC5", + hasRewards: true, + masterChef: "0xa976cb47C216Ee71089b10383bDEa4e230551458", description: "crypto prices", - version: "1.4.0", + version: "FILL THIS OUT", }, ], - info: { uploadBlockNumber: 15336699, graphName: "matic" }, + info: { uploadBlockNumber: 15336699, graphName: "mumbai" }, }, }; diff --git a/packages/smart/deployments/maticMumbai/CryptoCurrencyFetcher.json b/packages/smart/deployments/maticMumbai/CryptoCurrencyFetcher.json index 523a4a73c..dae6ec641 100644 --- a/packages/smart/deployments/maticMumbai/CryptoCurrencyFetcher.json +++ b/packages/smart/deployments/maticMumbai/CryptoCurrencyFetcher.json @@ -1,5 +1,5 @@ { - "address": "0x4D32E966a79bFB049Fc48655e6Ae8785ed34e44f", + "address": "0xdA65A1f9c322384F743C474040283897cDcE8cC5", "abi": [ { "inputs": [], @@ -386,21 +386,21 @@ "type": "function" } ], - "transactionHash": "0x7620f863aa3e34e91fdaa00b8316ae554b679e5086fa231b4e8fe90138ea35b8", + "transactionHash": "0x501546097d38f6340809c02227157cc13599c112d3fae615862ffd56a8aac1d4", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0x4D32E966a79bFB049Fc48655e6Ae8785ed34e44f", - "transactionIndex": 3, + "contractAddress": "0xdA65A1f9c322384F743C474040283897cDcE8cC5", + "transactionIndex": 1, "gasUsed": "1683591", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000000000000000000000000000000000000000000000800000000000000000080100000000000000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000024000000000000000000001000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x111ebdf4a9d4f5e0300da1271703beb6a58105df73aff891c0b6925fd221cefc", - "transactionHash": "0x7620f863aa3e34e91fdaa00b8316ae554b679e5086fa231b4e8fe90138ea35b8", + "blockHash": "0x7257df5ef587997e1e1093ae4617760a38e56eb57109de17897e2941ce4e0c1f", + "transactionHash": "0x501546097d38f6340809c02227157cc13599c112d3fae615862ffd56a8aac1d4", "logs": [ { - "transactionIndex": 3, - "blockNumber": 19809246, - "transactionHash": "0x7620f863aa3e34e91fdaa00b8316ae554b679e5086fa231b4e8fe90138ea35b8", + "transactionIndex": 1, + "blockNumber": 20388735, + "transactionHash": "0x501546097d38f6340809c02227157cc13599c112d3fae615862ffd56a8aac1d4", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -408,21 +408,21 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x0000000000000000000000000000000000000000000000000011f1a6ba81920000000000000000000000000000000000000000000000000365108dd05c62b72900000000000000000000000000000000000000000000000001a2f5d6fe1a580000000000000000000000000000000000000000000000000364fe9c29a1e1252900000000000000000000000000000000000000000000000001b4e77db89bea00", - "logIndex": 15, - "blockHash": "0x111ebdf4a9d4f5e0300da1271703beb6a58105df73aff891c0b6925fd221cefc" + "data": "0x00000000000000000000000000000000000000000000000000158861ac9b7c00000000000000000000000000000000000000000000000003343673bca306d474000000000000000000000000000000000000000000000000046983bf22fb5ef00000000000000000000000000000000000000000000000033420eb5af66b5874000000000000000000000000000000000000000000000000047f0c20cf96daf0", + "logIndex": 2, + "blockHash": "0x7257df5ef587997e1e1093ae4617760a38e56eb57109de17897e2941ce4e0c1f" } ], - "blockNumber": 19809246, - "cumulativeGasUsed": "2854239", + "blockNumber": 20388735, + "cumulativeGasUsed": "1704591", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle\",\"name\":\"super\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"resolutionValue\",\"type\":\"uint256\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificDynamicMarketBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestMarketIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle\",\"name\":\"super\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"coinIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionValue\",\"type\":\"uint256\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificStaticMarketBundle[]\",\"name\":\"_marketBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestMarketIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/Fetcher.sol\":\"CryptoCurrencyFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n HasSpreadMarket(Spread, InvalidName)\\n HasOverUnderMarket(OverUnder, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x0d4c083d82b07c94a03831f3b79e9cdc1f6016c3532199b03cbd7d81b7d2a757\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252600e81526d43727970746f43757272656e637960901b60208083019182528351808501909452600384526215109160ea1b908401528151919291620000639160009162000082565b5080516200007990600190602084019062000082565b5050506200012e565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000ba576000855562000105565b82601f10620000d557805160ff191683800117855562000105565b8280016001018555821562000105579182015b8281111562000105578251825591602001919060010190620000e8565b506200011392915062000117565b5090565b5b8082111562000113576000815560010162000118565b611c9b806200013e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611402565b6100bc565b6040516100749493929190611b13565b60405180910390f35b610085610197565b6040516100749190611b00565b610085610225565b6100ad6100a836600461145c565b61027f565b60405161007493929190611a0e565b6100c4611149565b60606000806100d289610344565b935060606100e18a888861035c565b81519750935090508567ffffffffffffffff8111801561010057600080fd5b5060405190808252806020026020018201604052801561013a57816020015b610127611161565b81526020019060019003908161011f5790505b50935060005b86811015610186576101678b8b8b85858151811061015a57fe5b60200260200101516104b7565b85828151811061017357fe5b6020908102919091010152600101610140565b504291505095509550955095915050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b6060600080606061029188878761035c565b81519650935090508467ffffffffffffffff811180156102b057600080fd5b506040519080825280602002602001820160405280156102ea57816020015b6102d7611196565b8152602001906001900390816102cf5790505b50935060005b8581101561033557610316898984848151811061030957fe5b6020026020010151610580565b85828151811061032257fe5b60209081029190910101526001016102f0565b50429150509450945094915050565b61034c611149565b61035582610626565b8152919050565b606060008267ffffffffffffffff8111801561037757600080fd5b506040519080825280602002602001820160405280156103a1578160200160208202803683370190505b50915060006001866001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156103e157600080fd5b505afa1580156103f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104199190611758565b0390508015806104295750808510155b156104475750506040805160008082526020820190925291506104af565b600085820392505b61045987846109a0565b1561047a578284828151811061046b57fe5b60209081029190910101526001015b848110610486576104a0565b8260011415610494576104a0565b6000199092019161044f565b808511156104ac578084525b50505b935093915050565b6104bf611161565b60405163b06c1ba360e01b81526000906001600160a01b0387169063b06c1ba3906104ee908690600401611bd2565b60806040518083038186803b15801561050657600080fd5b505afa15801561051a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053e9190611582565b905061054c86868686610ac4565b8252602080820151604080850191909152825191840191909152810151608083015260609081015190820152949350505050565b610588611196565b60405163b06c1ba360e01b81526000906001600160a01b0386169063b06c1ba3906105b7908690600401611bd2565b60806040518083038186803b1580156105cf57600080fd5b505afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106079190611582565b9050610614858585610c36565b82526040015160208201529392505050565b61062e6111b6565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b15801561066757600080fd5b505afa15801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069f9190611758565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e157600080fd5b505afa1580156106f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107199190611758565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b15801561075b57600080fd5b505afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190611758565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080d9190611758565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b15801561084f57600080fd5b505afa158015610863573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906114dc565b81608001906001600160a01b031690816001600160a01b03168152505061091d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e057600080fd5b505afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091891906114dc565b610cfa565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b15801561095e57600080fd5b505afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109969190611758565b60c0820152919050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016109cf9190611bd2565b60006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2391908101906115e1565b60408101519091506001600160a01b0316610a42576001915050610abe565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8157600080fd5b505afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190611758565b119150505b92915050565b610acc6111f5565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610afb908690600401611bd2565b60006040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4f91908101906115e1565b6001600160a01b0387168352602083018490529050610b6f868685610e07565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ba69088908a908890600401611ac3565b60a06040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906116eb565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610c3e61124d565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610c6d908690600401611bd2565b60006040518083038186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc191908101906115e1565b6001600160a01b0380871684526020840185905260408201511660608401529050610ced858585610e07565b6040830152509392505050565b610d02611279565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610d4557600080fd5b505afa158015610d59573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d8191908101906114f8565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610dc257600080fd5b505afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190611770565b60ff166040820152919050565b610e0f6112a3565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290610e409088908790600401611ae7565b60206040518083038186803b158015610e5857600080fd5b505afa158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9091906114dc565b90506001600160a01b038116610ea65750611142565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b158015610ee957600080fd5b505afa158015610efd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f219190611758565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990610f549088908790600401611ae7565b60206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190611758565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf390610fd79088908790600401611ae7565b60006040518083038186803b158015610fef57600080fd5b505afa158015611003573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102b91908101906114a1565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd906110609088908790600401611ae7565b60006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906114a1565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906110e79088908790600401611ae7565b60006040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261113b91908101906114a1565b6060830152505b9392505050565b604051806020016040528061115c6111b6565b905290565b6040518060a001604052806111746111f5565b8152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806111a961124d565b8152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016111a9611279565b6040805161010081018252600080825260208201529081016112156112a3565b81526020016112226112e2565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b604080516080810182526000808252602082015290810161126c6112a3565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161131e81611c4d565b919050565b600082601f830112611333578081fd5b8151602061134861134383611bff565b611bdb565b8281528181019085830183850287018401881015611364578586fd5b855b8581101561138b57815161137981611c4d565b84529284019290840190600101611366565b5090979650505050505050565b600082601f8301126113a8578081fd5b815160206113b861134383611bff565b82815281810190858301838502870184018810156113d4578586fd5b855b8581101561138b578151845292840192908401906001016113d6565b8051801515811461131e57600080fd5b600080600080600060a08688031215611419578081fd5b853561142481611c4d565b9450602086013561143481611c4d565b9350604086013561144481611c4d565b94979396509394606081013594506080013592915050565b60008060008060808587031215611471578081fd5b843561147c81611c4d565b9350602085013561148c81611c4d565b93969395505050506040820135916060013590565b6000602082840312156114b2578081fd5b815167ffffffffffffffff8111156114c8578182fd5b6114d484828501611398565b949350505050565b6000602082840312156114ed578081fd5b815161114281611c4d565b600060208284031215611509578081fd5b815167ffffffffffffffff80821115611520578283fd5b818401915084601f830112611533578283fd5b81518181111561153f57fe5b611552601f8201601f1916602001611bdb565b9150808252856020828501011115611568578384fd5b611579816020840160208601611c1d565b50949350505050565b600060808284031215611593578081fd5b6040516080810181811067ffffffffffffffff821117156115b057fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156115f2578081fd5b815167ffffffffffffffff80821115611609578283fd5b818401915061016080838703121561161f578384fd5b61162881611bdb565b905061163383611313565b8152602083015182811115611646578485fd5b61165287828601611323565b60208301525061166460408401611313565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151838111156116ba578586fd5b6116c688828701611398565b82840152505061014091506116dc8284016113f2565b91810191909152949350505050565b600060a082840312156116fc578081fd5b60405160a0810181811067ffffffffffffffff8211171561171957fe5b80604052508251815260208301516020820152604083015160408201526060830151606082015261174c608084016113f2565b60808201529392505050565b600060208284031215611769578081fd5b5051919050565b600060208284031215611781578081fd5b815160ff81168114611142578182fd5b6000815180845260208085019450808401835b838110156117c95781516001600160a01b0316875295820195908201906001016117a4565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b858110156118ec578284038952815160a081518187526118138288018251611928565b878101518060c08901525060408082015160e0610180818b015261183b6102208b0183611961565b91506060808501516118516101008d01826119dc565b50608080860151609f19808e8703016101a08f01526118708683611791565b988801516101c08f015260c08801519895506118906101e08f018a611928565b848801519850808e8703016102008f015250506118ad84886118f9565b888e01518d8f015285890151958d019590955281880151918c01919091529586015195909901949094529b88019b9650505091850191506001016117f0565b5091979650505050505050565b6000815180845260208085019450808401835b838110156117c95781518752958201959082019060010161190c565b6001600160a01b03169052565b6000815180845261194d816020860160208601611c1d565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c0602085015261198860c08501826118f9565b9050604083015184820360408601526119a182826118f9565b915050606083015184820360608601526119bb82826118f9565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015611aa757898303607f1901865281518051604080865281516001600160a01b0390811682880152878301518c880152908201518a87018b90529190611a8060c0880184611961565b918c01511660a0870152918601519486019490945295840195925090830190600101611a34565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526111426020830184611935565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a0860152611b926101e0860182611935565b905060408201516101c086015260c08301516101608601528481036020860152611bbc81896117d4565b6040860197909752505050506060015292915050565b90815260200190565b60405181810167ffffffffffffffff81118282101715611bf757fe5b604052919050565b600067ffffffffffffffff821115611c1357fe5b5060209081020190565b60005b83811015611c38578181015183820152602001611c20565b83811115611c47576000848401525b50505050565b6001600160a01b0381168114611c6257600080fd5b5056fea2646970667358221220e65368a5d03f8ba24a1736f5e945aecd1238dfd680ffb22ee65415e86f1dc9fe64736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611402565b6100bc565b6040516100749493929190611b13565b60405180910390f35b610085610197565b6040516100749190611b00565b610085610225565b6100ad6100a836600461145c565b61027f565b60405161007493929190611a0e565b6100c4611149565b60606000806100d289610344565b935060606100e18a888861035c565b81519750935090508567ffffffffffffffff8111801561010057600080fd5b5060405190808252806020026020018201604052801561013a57816020015b610127611161565b81526020019060019003908161011f5790505b50935060005b86811015610186576101678b8b8b85858151811061015a57fe5b60200260200101516104b7565b85828151811061017357fe5b6020908102919091010152600101610140565b504291505095509550955095915050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b6060600080606061029188878761035c565b81519650935090508467ffffffffffffffff811180156102b057600080fd5b506040519080825280602002602001820160405280156102ea57816020015b6102d7611196565b8152602001906001900390816102cf5790505b50935060005b8581101561033557610316898984848151811061030957fe5b6020026020010151610580565b85828151811061032257fe5b60209081029190910101526001016102f0565b50429150509450945094915050565b61034c611149565b61035582610626565b8152919050565b606060008267ffffffffffffffff8111801561037757600080fd5b506040519080825280602002602001820160405280156103a1578160200160208202803683370190505b50915060006001866001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156103e157600080fd5b505afa1580156103f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104199190611758565b0390508015806104295750808510155b156104475750506040805160008082526020820190925291506104af565b600085820392505b61045987846109a0565b1561047a578284828151811061046b57fe5b60209081029190910101526001015b848110610486576104a0565b8260011415610494576104a0565b6000199092019161044f565b808511156104ac578084525b50505b935093915050565b6104bf611161565b60405163b06c1ba360e01b81526000906001600160a01b0387169063b06c1ba3906104ee908690600401611bd2565b60806040518083038186803b15801561050657600080fd5b505afa15801561051a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053e9190611582565b905061054c86868686610ac4565b8252602080820151604080850191909152825191840191909152810151608083015260609081015190820152949350505050565b610588611196565b60405163b06c1ba360e01b81526000906001600160a01b0386169063b06c1ba3906105b7908690600401611bd2565b60806040518083038186803b1580156105cf57600080fd5b505afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106079190611582565b9050610614858585610c36565b82526040015160208201529392505050565b61062e6111b6565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b15801561066757600080fd5b505afa15801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069f9190611758565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e157600080fd5b505afa1580156106f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107199190611758565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b15801561075b57600080fd5b505afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190611758565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080d9190611758565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b15801561084f57600080fd5b505afa158015610863573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906114dc565b81608001906001600160a01b031690816001600160a01b03168152505061091d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e057600080fd5b505afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091891906114dc565b610cfa565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b15801561095e57600080fd5b505afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109969190611758565b60c0820152919050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016109cf9190611bd2565b60006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2391908101906115e1565b60408101519091506001600160a01b0316610a42576001915050610abe565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8157600080fd5b505afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190611758565b119150505b92915050565b610acc6111f5565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610afb908690600401611bd2565b60006040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4f91908101906115e1565b6001600160a01b0387168352602083018490529050610b6f868685610e07565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ba69088908a908890600401611ac3565b60a06040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906116eb565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610c3e61124d565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610c6d908690600401611bd2565b60006040518083038186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc191908101906115e1565b6001600160a01b0380871684526020840185905260408201511660608401529050610ced858585610e07565b6040830152509392505050565b610d02611279565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610d4557600080fd5b505afa158015610d59573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d8191908101906114f8565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610dc257600080fd5b505afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190611770565b60ff166040820152919050565b610e0f6112a3565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290610e409088908790600401611ae7565b60206040518083038186803b158015610e5857600080fd5b505afa158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9091906114dc565b90506001600160a01b038116610ea65750611142565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b158015610ee957600080fd5b505afa158015610efd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f219190611758565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990610f549088908790600401611ae7565b60206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190611758565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf390610fd79088908790600401611ae7565b60006040518083038186803b158015610fef57600080fd5b505afa158015611003573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102b91908101906114a1565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd906110609088908790600401611ae7565b60006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906114a1565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906110e79088908790600401611ae7565b60006040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261113b91908101906114a1565b6060830152505b9392505050565b604051806020016040528061115c6111b6565b905290565b6040518060a001604052806111746111f5565b8152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806111a961124d565b8152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016111a9611279565b6040805161010081018252600080825260208201529081016112156112a3565b81526020016112226112e2565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b604080516080810182526000808252602082015290810161126c6112a3565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161131e81611c4d565b919050565b600082601f830112611333578081fd5b8151602061134861134383611bff565b611bdb565b8281528181019085830183850287018401881015611364578586fd5b855b8581101561138b57815161137981611c4d565b84529284019290840190600101611366565b5090979650505050505050565b600082601f8301126113a8578081fd5b815160206113b861134383611bff565b82815281810190858301838502870184018810156113d4578586fd5b855b8581101561138b578151845292840192908401906001016113d6565b8051801515811461131e57600080fd5b600080600080600060a08688031215611419578081fd5b853561142481611c4d565b9450602086013561143481611c4d565b9350604086013561144481611c4d565b94979396509394606081013594506080013592915050565b60008060008060808587031215611471578081fd5b843561147c81611c4d565b9350602085013561148c81611c4d565b93969395505050506040820135916060013590565b6000602082840312156114b2578081fd5b815167ffffffffffffffff8111156114c8578182fd5b6114d484828501611398565b949350505050565b6000602082840312156114ed578081fd5b815161114281611c4d565b600060208284031215611509578081fd5b815167ffffffffffffffff80821115611520578283fd5b818401915084601f830112611533578283fd5b81518181111561153f57fe5b611552601f8201601f1916602001611bdb565b9150808252856020828501011115611568578384fd5b611579816020840160208601611c1d565b50949350505050565b600060808284031215611593578081fd5b6040516080810181811067ffffffffffffffff821117156115b057fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156115f2578081fd5b815167ffffffffffffffff80821115611609578283fd5b818401915061016080838703121561161f578384fd5b61162881611bdb565b905061163383611313565b8152602083015182811115611646578485fd5b61165287828601611323565b60208301525061166460408401611313565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151838111156116ba578586fd5b6116c688828701611398565b82840152505061014091506116dc8284016113f2565b91810191909152949350505050565b600060a082840312156116fc578081fd5b60405160a0810181811067ffffffffffffffff8211171561171957fe5b80604052508251815260208301516020820152604083015160408201526060830151606082015261174c608084016113f2565b60808201529392505050565b600060208284031215611769578081fd5b5051919050565b600060208284031215611781578081fd5b815160ff81168114611142578182fd5b6000815180845260208085019450808401835b838110156117c95781516001600160a01b0316875295820195908201906001016117a4565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b858110156118ec578284038952815160a081518187526118138288018251611928565b878101518060c08901525060408082015160e0610180818b015261183b6102208b0183611961565b91506060808501516118516101008d01826119dc565b50608080860151609f19808e8703016101a08f01526118708683611791565b988801516101c08f015260c08801519895506118906101e08f018a611928565b848801519850808e8703016102008f015250506118ad84886118f9565b888e01518d8f015285890151958d019590955281880151918c01919091529586015195909901949094529b88019b9650505091850191506001016117f0565b5091979650505050505050565b6000815180845260208085019450808401835b838110156117c95781518752958201959082019060010161190c565b6001600160a01b03169052565b6000815180845261194d816020860160208601611c1d565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c0602085015261198860c08501826118f9565b9050604083015184820360408601526119a182826118f9565b915050606083015184820360608601526119bb82826118f9565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015611aa757898303607f1901865281518051604080865281516001600160a01b0390811682880152878301518c880152908201518a87018b90529190611a8060c0880184611961565b918c01511660a0870152918601519486019490945295840195925090830190600101611a34565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526111426020830184611935565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a0860152611b926101e0860182611935565b905060408201516101c086015260c08301516101608601528481036020860152611bbc81896117d4565b6040860197909752505050506060015292915050565b90815260200190565b60405181810167ffffffffffffffff81118282101715611bf757fe5b604052919050565b600067ffffffffffffffff821115611c1357fe5b5060209081020190565b60005b83811015611c38578181015183820152602001611c20565b83811115611c47576000848401525b50505050565b6001600160a01b0381168114611c6257600080fd5b5056fea2646970667358221220e65368a5d03f8ba24a1736f5e945aecd1238dfd680ffb22ee65415e86f1dc9fe64736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle\",\"name\":\"super\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"resolutionValue\",\"type\":\"uint256\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificDynamicMarketBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestMarketIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle\",\"name\":\"super\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"coinIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionValue\",\"type\":\"uint256\"}],\"internalType\":\"struct CryptoCurrencyFetcher.SpecificStaticMarketBundle[]\",\"name\":\"_marketBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestMarketIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/Fetcher.sol\":\"CryptoCurrencyFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant Spread = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.5.0\\\")\\n ManagedByLink(_linkNode)\\n HasSpreadMarket(Spread, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n makeLine(_homeSpread),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\\n internal\\n returns (uint256[] memory _marketIds)\\n {\\n _marketIds = new uint256[](1);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n }\\n\\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\\n _line = build1Line();\\n _line[0] = addHalfPoint(_homeSpread);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x2187210295b55bd841518dc83cb592ef7365c4d7ba4f38895865e4d26ccefe35\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252600e81526d43727970746f43757272656e637960901b60208083019182528351808501909452600384526215109160ea1b908401528151919291620000639160009162000082565b5080516200007990600190602084019062000082565b5050506200012e565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000ba576000855562000105565b82601f10620000d557805160ff191683800117855562000105565b8280016001018555821562000105579182015b8281111562000105578251825591602001919060010190620000e8565b506200011392915062000117565b5090565b5b8082111562000113576000815560010162000118565b611c9b806200013e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611402565b6100bc565b6040516100749493929190611b13565b60405180910390f35b610085610197565b6040516100749190611b00565b610085610225565b6100ad6100a836600461145c565b61027f565b60405161007493929190611a0e565b6100c4611149565b60606000806100d289610344565b935060606100e18a888861035c565b81519750935090508567ffffffffffffffff8111801561010057600080fd5b5060405190808252806020026020018201604052801561013a57816020015b610127611161565b81526020019060019003908161011f5790505b50935060005b86811015610186576101678b8b8b85858151811061015a57fe5b60200260200101516104b7565b85828151811061017357fe5b6020908102919091010152600101610140565b504291505095509550955095915050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b6060600080606061029188878761035c565b81519650935090508467ffffffffffffffff811180156102b057600080fd5b506040519080825280602002602001820160405280156102ea57816020015b6102d7611196565b8152602001906001900390816102cf5790505b50935060005b8581101561033557610316898984848151811061030957fe5b6020026020010151610580565b85828151811061032257fe5b60209081029190910101526001016102f0565b50429150509450945094915050565b61034c611149565b61035582610626565b8152919050565b606060008267ffffffffffffffff8111801561037757600080fd5b506040519080825280602002602001820160405280156103a1578160200160208202803683370190505b50915060006001866001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156103e157600080fd5b505afa1580156103f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104199190611758565b0390508015806104295750808510155b156104475750506040805160008082526020820190925291506104af565b600085820392505b61045987846109a0565b1561047a578284828151811061046b57fe5b60209081029190910101526001015b848110610486576104a0565b8260011415610494576104a0565b6000199092019161044f565b808511156104ac578084525b50505b935093915050565b6104bf611161565b60405163b06c1ba360e01b81526000906001600160a01b0387169063b06c1ba3906104ee908690600401611bd2565b60806040518083038186803b15801561050657600080fd5b505afa15801561051a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053e9190611582565b905061054c86868686610ac4565b8252602080820151604080850191909152825191840191909152810151608083015260609081015190820152949350505050565b610588611196565b60405163b06c1ba360e01b81526000906001600160a01b0386169063b06c1ba3906105b7908690600401611bd2565b60806040518083038186803b1580156105cf57600080fd5b505afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106079190611582565b9050610614858585610c36565b82526040015160208201529392505050565b61062e6111b6565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b15801561066757600080fd5b505afa15801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069f9190611758565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e157600080fd5b505afa1580156106f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107199190611758565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b15801561075b57600080fd5b505afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190611758565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080d9190611758565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b15801561084f57600080fd5b505afa158015610863573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906114dc565b81608001906001600160a01b031690816001600160a01b03168152505061091d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e057600080fd5b505afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091891906114dc565b610cfa565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b15801561095e57600080fd5b505afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109969190611758565b60c0820152919050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016109cf9190611bd2565b60006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2391908101906115e1565b60408101519091506001600160a01b0316610a42576001915050610abe565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8157600080fd5b505afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190611758565b119150505b92915050565b610acc6111f5565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610afb908690600401611bd2565b60006040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4f91908101906115e1565b6001600160a01b0387168352602083018490529050610b6f868685610e07565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ba69088908a908890600401611ac3565b60a06040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906116eb565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610c3e61124d565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610c6d908690600401611bd2565b60006040518083038186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc191908101906115e1565b6001600160a01b0380871684526020840185905260408201511660608401529050610ced858585610e07565b6040830152509392505050565b610d02611279565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610d4557600080fd5b505afa158015610d59573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d8191908101906114f8565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610dc257600080fd5b505afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190611770565b60ff166040820152919050565b610e0f6112a3565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290610e409088908790600401611ae7565b60206040518083038186803b158015610e5857600080fd5b505afa158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9091906114dc565b90506001600160a01b038116610ea65750611142565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b158015610ee957600080fd5b505afa158015610efd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f219190611758565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990610f549088908790600401611ae7565b60206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190611758565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf390610fd79088908790600401611ae7565b60006040518083038186803b158015610fef57600080fd5b505afa158015611003573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102b91908101906114a1565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd906110609088908790600401611ae7565b60006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906114a1565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906110e79088908790600401611ae7565b60006040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261113b91908101906114a1565b6060830152505b9392505050565b604051806020016040528061115c6111b6565b905290565b6040518060a001604052806111746111f5565b8152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806111a961124d565b8152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016111a9611279565b6040805161010081018252600080825260208201529081016112156112a3565b81526020016112226112e2565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b604080516080810182526000808252602082015290810161126c6112a3565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161131e81611c4d565b919050565b600082601f830112611333578081fd5b8151602061134861134383611bff565b611bdb565b8281528181019085830183850287018401881015611364578586fd5b855b8581101561138b57815161137981611c4d565b84529284019290840190600101611366565b5090979650505050505050565b600082601f8301126113a8578081fd5b815160206113b861134383611bff565b82815281810190858301838502870184018810156113d4578586fd5b855b8581101561138b578151845292840192908401906001016113d6565b8051801515811461131e57600080fd5b600080600080600060a08688031215611419578081fd5b853561142481611c4d565b9450602086013561143481611c4d565b9350604086013561144481611c4d565b94979396509394606081013594506080013592915050565b60008060008060808587031215611471578081fd5b843561147c81611c4d565b9350602085013561148c81611c4d565b93969395505050506040820135916060013590565b6000602082840312156114b2578081fd5b815167ffffffffffffffff8111156114c8578182fd5b6114d484828501611398565b949350505050565b6000602082840312156114ed578081fd5b815161114281611c4d565b600060208284031215611509578081fd5b815167ffffffffffffffff80821115611520578283fd5b818401915084601f830112611533578283fd5b81518181111561153f57fe5b611552601f8201601f1916602001611bdb565b9150808252856020828501011115611568578384fd5b611579816020840160208601611c1d565b50949350505050565b600060808284031215611593578081fd5b6040516080810181811067ffffffffffffffff821117156115b057fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156115f2578081fd5b815167ffffffffffffffff80821115611609578283fd5b818401915061016080838703121561161f578384fd5b61162881611bdb565b905061163383611313565b8152602083015182811115611646578485fd5b61165287828601611323565b60208301525061166460408401611313565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151838111156116ba578586fd5b6116c688828701611398565b82840152505061014091506116dc8284016113f2565b91810191909152949350505050565b600060a082840312156116fc578081fd5b60405160a0810181811067ffffffffffffffff8211171561171957fe5b80604052508251815260208301516020820152604083015160408201526060830151606082015261174c608084016113f2565b60808201529392505050565b600060208284031215611769578081fd5b5051919050565b600060208284031215611781578081fd5b815160ff81168114611142578182fd5b6000815180845260208085019450808401835b838110156117c95781516001600160a01b0316875295820195908201906001016117a4565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b858110156118ec578284038952815160a081518187526118138288018251611928565b878101518060c08901525060408082015160e0610180818b015261183b6102208b0183611961565b91506060808501516118516101008d01826119dc565b50608080860151609f19808e8703016101a08f01526118708683611791565b988801516101c08f015260c08801519895506118906101e08f018a611928565b848801519850808e8703016102008f015250506118ad84886118f9565b888e01518d8f015285890151958d019590955281880151918c01919091529586015195909901949094529b88019b9650505091850191506001016117f0565b5091979650505050505050565b6000815180845260208085019450808401835b838110156117c95781518752958201959082019060010161190c565b6001600160a01b03169052565b6000815180845261194d816020860160208601611c1d565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c0602085015261198860c08501826118f9565b9050604083015184820360408601526119a182826118f9565b915050606083015184820360608601526119bb82826118f9565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015611aa757898303607f1901865281518051604080865281516001600160a01b0390811682880152878301518c880152908201518a87018b90529190611a8060c0880184611961565b918c01511660a0870152918601519486019490945295840195925090830190600101611a34565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526111426020830184611935565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a0860152611b926101e0860182611935565b905060408201516101c086015260c08301516101608601528481036020860152611bbc81896117d4565b6040860197909752505050506060015292915050565b90815260200190565b60405181810167ffffffffffffffff81118282101715611bf757fe5b604052919050565b600067ffffffffffffffff821115611c1357fe5b5060209081020190565b60005b83811015611c38578181015183820152602001611c20565b83811115611c47576000848401525b50505050565b6001600160a01b0381168114611c6257600080fd5b5056fea26469706673582212205f656f1d0a436061128007b2e050afeb97c4dd332da68c6df39ba21d3aafb1bc64736f6c63430007060033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611402565b6100bc565b6040516100749493929190611b13565b60405180910390f35b610085610197565b6040516100749190611b00565b610085610225565b6100ad6100a836600461145c565b61027f565b60405161007493929190611a0e565b6100c4611149565b60606000806100d289610344565b935060606100e18a888861035c565b81519750935090508567ffffffffffffffff8111801561010057600080fd5b5060405190808252806020026020018201604052801561013a57816020015b610127611161565b81526020019060019003908161011f5790505b50935060005b86811015610186576101678b8b8b85858151811061015a57fe5b60200260200101516104b7565b85828151811061017357fe5b6020908102919091010152600101610140565b504291505095509550955095915050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b820191906000526020600020905b81548152906001019060200180831161020057829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561021d5780601f106101f25761010080835404028352916020019161021d565b6060600080606061029188878761035c565b81519650935090508467ffffffffffffffff811180156102b057600080fd5b506040519080825280602002602001820160405280156102ea57816020015b6102d7611196565b8152602001906001900390816102cf5790505b50935060005b8581101561033557610316898984848151811061030957fe5b6020026020010151610580565b85828151811061032257fe5b60209081029190910101526001016102f0565b50429150509450945094915050565b61034c611149565b61035582610626565b8152919050565b606060008267ffffffffffffffff8111801561037757600080fd5b506040519080825280602002602001820160405280156103a1578160200160208202803683370190505b50915060006001866001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156103e157600080fd5b505afa1580156103f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104199190611758565b0390508015806104295750808510155b156104475750506040805160008082526020820190925291506104af565b600085820392505b61045987846109a0565b1561047a578284828151811061046b57fe5b60209081029190910101526001015b848110610486576104a0565b8260011415610494576104a0565b6000199092019161044f565b808511156104ac578084525b50505b935093915050565b6104bf611161565b60405163b06c1ba360e01b81526000906001600160a01b0387169063b06c1ba3906104ee908690600401611bd2565b60806040518083038186803b15801561050657600080fd5b505afa15801561051a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053e9190611582565b905061054c86868686610ac4565b8252602080820151604080850191909152825191840191909152810151608083015260609081015190820152949350505050565b610588611196565b60405163b06c1ba360e01b81526000906001600160a01b0386169063b06c1ba3906105b7908690600401611bd2565b60806040518083038186803b1580156105cf57600080fd5b505afa1580156105e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106079190611582565b9050610614858585610c36565b82526040015160208201529392505050565b61062e6111b6565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b15801561066757600080fd5b505afa15801561067b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069f9190611758565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e157600080fd5b505afa1580156106f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107199190611758565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b15801561075b57600080fd5b505afa15801561076f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107939190611758565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107d557600080fd5b505afa1580156107e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080d9190611758565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b15801561084f57600080fd5b505afa158015610863573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088791906114dc565b81608001906001600160a01b031690816001600160a01b03168152505061091d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b1580156108e057600080fd5b505afa1580156108f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091891906114dc565b610cfa565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b15801561095e57600080fd5b505afa158015610972573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109969190611758565b60c0820152919050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016109cf9190611bd2565b60006040518083038186803b1580156109e757600080fd5b505afa1580156109fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a2391908101906115e1565b60408101519091506001600160a01b0316610a42576001915050610abe565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8157600080fd5b505afa158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190611758565b119150505b92915050565b610acc6111f5565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610afb908690600401611bd2565b60006040518083038186803b158015610b1357600080fd5b505afa158015610b27573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4f91908101906115e1565b6001600160a01b0387168352602083018490529050610b6f868685610e07565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ba69088908a908890600401611ac3565b60a06040518083038186803b158015610bbe57600080fd5b505afa158015610bd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf691906116eb565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610c3e61124d565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610c6d908690600401611bd2565b60006040518083038186803b158015610c8557600080fd5b505afa158015610c99573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc191908101906115e1565b6001600160a01b0380871684526020840185905260408201511660608401529050610ced858585610e07565b6040830152509392505050565b610d02611279565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610d4557600080fd5b505afa158015610d59573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d8191908101906114f8565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610dc257600080fd5b505afa158015610dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfa9190611770565b60ff166040820152919050565b610e0f6112a3565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290610e409088908790600401611ae7565b60206040518083038186803b158015610e5857600080fd5b505afa158015610e6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9091906114dc565b90506001600160a01b038116610ea65750611142565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b158015610ee957600080fd5b505afa158015610efd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f219190611758565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990610f549088908790600401611ae7565b60206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa49190611758565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf390610fd79088908790600401611ae7565b60006040518083038186803b158015610fef57600080fd5b505afa158015611003573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261102b91908101906114a1565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd906110609088908790600401611ae7565b60006040518083038186803b15801561107857600080fd5b505afa15801561108c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b491908101906114a1565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906110e79088908790600401611ae7565b60006040518083038186803b1580156110ff57600080fd5b505afa158015611113573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261113b91908101906114a1565b6060830152505b9392505050565b604051806020016040528061115c6111b6565b905290565b6040518060a001604052806111746111f5565b8152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806111a961124d565b8152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016111a9611279565b6040805161010081018252600080825260208201529081016112156112a3565b81526020016112226112e2565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b604080516080810182526000808252602082015290810161126c6112a3565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161131e81611c4d565b919050565b600082601f830112611333578081fd5b8151602061134861134383611bff565b611bdb565b8281528181019085830183850287018401881015611364578586fd5b855b8581101561138b57815161137981611c4d565b84529284019290840190600101611366565b5090979650505050505050565b600082601f8301126113a8578081fd5b815160206113b861134383611bff565b82815281810190858301838502870184018810156113d4578586fd5b855b8581101561138b578151845292840192908401906001016113d6565b8051801515811461131e57600080fd5b600080600080600060a08688031215611419578081fd5b853561142481611c4d565b9450602086013561143481611c4d565b9350604086013561144481611c4d565b94979396509394606081013594506080013592915050565b60008060008060808587031215611471578081fd5b843561147c81611c4d565b9350602085013561148c81611c4d565b93969395505050506040820135916060013590565b6000602082840312156114b2578081fd5b815167ffffffffffffffff8111156114c8578182fd5b6114d484828501611398565b949350505050565b6000602082840312156114ed578081fd5b815161114281611c4d565b600060208284031215611509578081fd5b815167ffffffffffffffff80821115611520578283fd5b818401915084601f830112611533578283fd5b81518181111561153f57fe5b611552601f8201601f1916602001611bdb565b9150808252856020828501011115611568578384fd5b611579816020840160208601611c1d565b50949350505050565b600060808284031215611593578081fd5b6040516080810181811067ffffffffffffffff821117156115b057fe5b8060405250825181526020830151602082015260408301516040820152606083015160608201528091505092915050565b6000602082840312156115f2578081fd5b815167ffffffffffffffff80821115611609578283fd5b818401915061016080838703121561161f578384fd5b61162881611bdb565b905061163383611313565b8152602083015182811115611646578485fd5b61165287828601611323565b60208301525061166460408401611313565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010080840151818301525061012080840151838111156116ba578586fd5b6116c688828701611398565b82840152505061014091506116dc8284016113f2565b91810191909152949350505050565b600060a082840312156116fc578081fd5b60405160a0810181811067ffffffffffffffff8211171561171957fe5b80604052508251815260208301516020820152604083015160408201526060830151606082015261174c608084016113f2565b60808201529392505050565b600060208284031215611769578081fd5b5051919050565b600060208284031215611781578081fd5b815160ff81168114611142578182fd5b6000815180845260208085019450808401835b838110156117c95781516001600160a01b0316875295820195908201906001016117a4565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b858110156118ec578284038952815160a081518187526118138288018251611928565b878101518060c08901525060408082015160e0610180818b015261183b6102208b0183611961565b91506060808501516118516101008d01826119dc565b50608080860151609f19808e8703016101a08f01526118708683611791565b988801516101c08f015260c08801519895506118906101e08f018a611928565b848801519850808e8703016102008f015250506118ad84886118f9565b888e01518d8f015285890151958d019590955281880151918c01919091529586015195909901949094529b88019b9650505091850191506001016117f0565b5091979650505050505050565b6000815180845260208085019450808401835b838110156117c95781518752958201959082019060010161190c565b6001600160a01b03169052565b6000815180845261194d816020860160208601611c1d565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c0602085015261198860c08501826118f9565b9050604083015184820360408601526119a182826118f9565b915050606083015184820360608601526119bb82826118f9565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015611aa757898303607f1901865281518051604080865281516001600160a01b0390811682880152878301518c880152908201518a87018b90529190611a8060c0880184611961565b918c01511660a0870152918601519486019490945295840195925090830190600101611a34565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526111426020830184611935565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a0860152611b926101e0860182611935565b905060408201516101c086015260c08301516101608601528481036020860152611bbc81896117d4565b6040860197909752505050506060015292915050565b90815260200190565b60405181810167ffffffffffffffff81118282101715611bf757fe5b604052919050565b600067ffffffffffffffff821115611c1357fe5b5060209081020190565b60005b83811015611c38578181015183820152602001611c20565b83811115611c47576000848401525b50505050565b6001600160a01b0381168114611c6257600080fd5b5056fea26469706673582212205f656f1d0a436061128007b2e050afeb97c4dd332da68c6df39ba21d3aafb1bc64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/smart/deployments/maticMumbai/GroupedFetcher.json b/packages/smart/deployments/maticMumbai/GroupedFetcher.json index ed1163608..f2120ab4b 100644 --- a/packages/smart/deployments/maticMumbai/GroupedFetcher.json +++ b/packages/smart/deployments/maticMumbai/GroupedFetcher.json @@ -1,5 +1,5 @@ { - "address": "0xEBC839dA45b1045bE3b02912714d55F592575157", + "address": "0xDB1FDD47b2dDc7d98698e8248202A56FCB7De53B", "abi": [ { "inputs": [], @@ -571,43 +571,43 @@ "type": "function" } ], - "transactionHash": "0xab5598bc9a85d3b126bcd9794d4e9d7aa03ec81c64205f1dc2809f383470feca", + "transactionHash": "0x5f556d14a32c50267c811ebec398481623bfcc4a99716f70b7ee81042e384fa0", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0xEBC839dA45b1045bE3b02912714d55F592575157", - "transactionIndex": 1, + "contractAddress": "0xDB1FDD47b2dDc7d98698e8248202A56FCB7De53B", + "transactionIndex": 2, "gasUsed": "2043843", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000000000000000000000000000000000000000000000800000000000000000080100000000000000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000024000000000000000000001000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x64d1302b4ea3068c03a5d21c8579b35c47c9fa88df61176f7029c2fab71b3b61", - "transactionHash": "0xab5598bc9a85d3b126bcd9794d4e9d7aa03ec81c64205f1dc2809f383470feca", + "logsBloom": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000020000000000000000000000000000000000000000000000000008000000000000000000c0100000000000000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000040000000004000000000000000000001000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000100000", + "blockHash": "0x9eadd197a0eed641ddb17cbce200aad3bdbe820ef62ef2cf923ee6a64ceef8b2", + "transactionHash": "0x5f556d14a32c50267c811ebec398481623bfcc4a99716f70b7ee81042e384fa0", "logs": [ { - "transactionIndex": 1, - "blockNumber": 19809250, - "transactionHash": "0xab5598bc9a85d3b126bcd9794d4e9d7aa03ec81c64205f1dc2809f383470feca", + "transactionIndex": 2, + "blockNumber": 20388736, + "transactionHash": "0x5f556d14a32c50267c811ebec398481623bfcc4a99716f70b7ee81042e384fa0", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", - "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" + "0x000000000000000000000000c275dc8be39f50d12f66b6a63629c39da5bae5bd" ], - "data": "0x0000000000000000000000000000000000000000000000000015c897d7f99a0000000000000000000000000000000000000000000000000364fe9c29a1e1252900000000000000000000000000000000000000000000000001c4609a3abe5a0000000000000000000000000000000000000000000000000364e8d391c9e78b2900000000000000000000000000000000000000000000000001da293212b7f400", - "logIndex": 2, - "blockHash": "0x64d1302b4ea3068c03a5d21c8579b35c47c9fa88df61176f7029c2fab71b3b61" + "data": "0x000000000000000000000000000000000000000000000000001d0b751ff778000000000000000000000000000000000000000000000000033420eb5af66b58740000000000000000000000000000000000000000000001a7ffffd1ea54f696370000000000000000000000000000000000000000000000033403dfe5d673e0740000000000000000000000000000000000000000000001a8001cdd5f74ee0e37", + "logIndex": 4, + "blockHash": "0x9eadd197a0eed641ddb17cbce200aad3bdbe820ef62ef2cf923ee6a64ceef8b2" } ], - "blockNumber": 19809250, - "cumulativeGasUsed": "2064843", + "blockNumber": 20388736, + "cumulativeGasUsed": "2232101", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle\",\"name\":\"invalidMarket\",\"type\":\"tuple\"}],\"internalType\":\"struct GroupFetcher.DynamicGroupBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestGroupIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct GroupFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle\",\"name\":\"invalidMarket\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"internalType\":\"struct GroupFetcher.StaticGroupBundle[]\",\"name\":\"_groupBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestGroupIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/GroupFetcher.sol\":\"GroupedFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/GroupFetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Fetcher.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\n\\nabstract contract GroupFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticGroupBundle {\\n uint256 id;\\n string name;\\n StaticMarketBundle[] markets;\\n string[] marketNames;\\n StaticMarketBundle invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n // Dynamics\\n Grouped.GroupStatus status;\\n }\\n\\n struct DynamicGroupBundle {\\n uint256 id;\\n Grouped.GroupStatus status;\\n DynamicMarketBundle[] markets;\\n DynamicMarketBundle invalidMarket;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticGroupBundle[] memory _groupBundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_groupBundles, _lowestGroupIndex) = buildStaticGroupBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicGroupBundle[] memory _bundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestGroupIndex) = buildDynamicGroupBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new StaticGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticGroupBundle(_marketFactory, _ammFactory, _masterChef, _groupIds[i]);\\n }\\n }\\n\\n function buildDynamicGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new DynamicGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicGroupBundle(_marketFactory, _ammFactory, _groupIds[i]);\\n }\\n }\\n\\n function buildStaticGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _groupId\\n ) internal view returns (StaticGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.name = _group.name;\\n _bundle.status = _group.status;\\n _bundle.markets = _markets;\\n _bundle.endTime = _group.endTime;\\n _bundle.invalidMarket = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.invalidMarket\\n );\\n _bundle.invalidMarketName = _group.invalidMarketName;\\n _bundle.marketNames = _group.marketNames;\\n _bundle.category = _group.category;\\n }\\n\\n function buildDynamicGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _groupId\\n ) internal view returns (DynamicGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.markets = _markets;\\n _bundle.invalidMarket = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.invalidMarket\\n );\\n _bundle.status = _group.status;\\n }\\n\\n // Starts from the end of the groups list because newer groups are more interesting.\\n // _offset is skipping all groups, not just interesting groups\\n function listOfInterestingGroups(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingGroupIds, uint256 _groupIndex) {\\n _interestingGroupIds = new uint256[](_total);\\n\\n uint256 _groupCount = Grouped(_marketFactory).groupCount();\\n\\n // No groups so return nothing. (needed to avoid integer underflow below)\\n if (_groupCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _groupCount;\\n\\n // No remaining groups so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedGroups = 0;\\n _groupIndex = _max - _offset;\\n while (true) {\\n if (_collectedGroups >= _total) break;\\n if (_groupIndex == 0) break;\\n\\n _groupIndex--; // starts out one too high, so this works\\n\\n (Grouped.MarketGroup memory _group, uint256 _groupId) =\\n Grouped(_marketFactory).getGroupByIndex(_groupIndex);\\n\\n if (isGroupInteresting(_group, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingGroupIds[_collectedGroups] = _groupId;\\n _collectedGroups++;\\n }\\n }\\n\\n if (_total > _collectedGroups) {\\n assembly {\\n // shortens array\\n mstore(_interestingGroupIds, _collectedGroups)\\n }\\n }\\n }\\n\\n function isGroupInteresting(Grouped.MarketGroup memory _group, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _group.markets.length; i++) {\\n uint256 _marketId = _group.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n if (openOrHasWinningShares(_marketFactory, _group.invalidMarket)) {\\n return true;\\n }\\n\\n return false;\\n }\\n}\\n\\ncontract GroupedFetcher is GroupFetcher {\\n constructor() Fetcher(\\\"Grouped\\\", \\\"TBD\\\") {}\\n}\\n\",\"keccak256\":\"0xd8cb93eee1737373d56fd149e2bbbf81a3b1b0f6516bfc217acc402105474cfc\",\"license\":\"MIT\"},\"contracts/turbo/Grouped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./GroupFetcher.sol\\\";\\n\\nabstract contract Grouped is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds {\\n event GroupCreated(uint256 indexed id, uint256 endTime, uint256 invalidMarketId, string invalidMarketName);\\n event GroupMarketAdded(uint256 indexed groupId, uint256 marketId, string marketName);\\n event GroupFinalizing(uint256 indexed groupId, uint256 winningMarketIndex);\\n event GroupResolved(uint256 indexed id, bool valid);\\n\\n enum GroupStatus {Unknown, Scheduled, Finalizing, Final, Invalid}\\n\\n struct MarketGroup {\\n GroupStatus status;\\n string name;\\n uint256[] markets;\\n string[] marketNames;\\n uint256 invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n uint256 winningMarketIndex; // ignore when status is Scheduled. MAX_UINT is invalid\\n }\\n // GroupId => MarketGroup\\n mapping(uint256 => MarketGroup) public marketGroups;\\n uint256[] public listOfMarketGroups;\\n\\n // For regular markets, YES means the team won and NO means the team did not win.\\n // For the invalid market, YES means none of the teams won and NO means a team won.\\n uint256 constant OUTCOME_NO = 0;\\n uint256 constant OUTCOME_YES = 1;\\n\\n uint256 constant MAX_UINT = 2**256 - 1;\\n\\n function groupCount() public view returns (uint256) {\\n return listOfMarketGroups.length;\\n }\\n\\n function getGroup(uint256 _groupId) public view returns (MarketGroup memory) {\\n return marketGroups[_groupId];\\n }\\n\\n function getGroupByIndex(uint256 _index) public view returns (MarketGroup memory _group, uint256 _groupId) {\\n _groupId = listOfMarketGroups[_index];\\n _group = getGroup(_groupId);\\n }\\n\\n function startCreatingMarketGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n uint256 _endTime,\\n string memory _invalidMarketName,\\n string memory _category\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Unknown, \\\"group exists\\\");\\n\\n listOfMarketGroups.push(_groupId);\\n marketGroups[_groupId].status = GroupStatus.Scheduled;\\n marketGroups[_groupId].name = _groupName;\\n marketGroups[_groupId].endTime = _endTime;\\n marketGroups[_groupId].category = _category;\\n\\n uint256 _invalidMarket = startMarket(msg.sender, buildOutcomesNames(_invalidMarketName), invalidOdds(), true);\\n marketGroups[_groupId].invalidMarket = _invalidMarket;\\n marketGroups[_groupId].invalidMarketName = _invalidMarketName;\\n\\n emit GroupCreated(_groupId, _endTime, _invalidMarket, _invalidMarketName);\\n emit GroupMarketAdded(_groupId, _invalidMarket, _invalidMarketName);\\n }\\n\\n function addMarketToMarketGroup(\\n uint256 _groupId,\\n string memory _marketName,\\n uint256[] memory _odds\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Scheduled, \\\"group must be Scheduled\\\");\\n\\n uint256 _marketId = startMarket(msg.sender, buildOutcomesNames(_marketName), _odds, true);\\n marketGroups[_groupId].markets.push(_marketId);\\n marketGroups[_groupId].marketNames.push(_marketName);\\n emit GroupMarketAdded(_groupId, _marketId, _marketName);\\n }\\n\\n // Use MAX_UINT for _winningMarketIndex to indicate INVALID\\n function startResolvingMarketGroup(uint256 _groupId, uint256 _winningMarketIndex) internal {\\n bool _isInvalid = _winningMarketIndex == MAX_UINT;\\n MarketGroup memory _group = marketGroups[_groupId];\\n\\n require(_group.status == GroupStatus.Scheduled, \\\"group not Scheduled\\\");\\n\\n resolveInvalidMarket(_group, _isInvalid);\\n marketGroups[_groupId].status = GroupStatus.Finalizing;\\n marketGroups[_groupId].winningMarketIndex = _winningMarketIndex;\\n emit GroupFinalizing(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveFinalizingGroupMarket(uint256 _groupId, uint256 _marketIndex) internal {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing, \\\"must be finalizing\\\");\\n\\n uint256 _marketId = _group.markets[_marketIndex];\\n bool _wins = _marketIndex == _group.winningMarketIndex;\\n resolveGroupMarket(_marketId, _wins);\\n }\\n\\n function finalizeMarketGroup(uint256 _groupId) internal {\\n MarketGroup storage _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n bool _valid = _group.winningMarketIndex != MAX_UINT;\\n\\n _group.status = _valid ? GroupStatus.Final : GroupStatus.Invalid;\\n\\n emit GroupResolved(_groupId, _valid);\\n }\\n\\n function resolveGroupMarket(uint256 _marketId, bool _wins) internal {\\n uint256 _winningOutcome = _wins ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_marketId, _winningOutcome);\\n }\\n\\n function resolveInvalidMarket(MarketGroup memory _group, bool _invalid) private {\\n uint256 _outcomeIndex = _invalid ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_group.invalidMarket, _outcomeIndex);\\n }\\n\\n function buildOutcomesNames(string memory _marketName) internal pure returns (string[] memory _names) {\\n _names = new string[](2);\\n _names[OUTCOME_NO] = string(abi.encodePacked(\\\"NO - \\\", _marketName));\\n _names[OUTCOME_YES] = string(abi.encodePacked(\\\"YES - \\\", _marketName));\\n }\\n\\n function invalidOdds() private pure returns (uint256[] memory _odds) {\\n _odds = new uint256[](2);\\n _odds[OUTCOME_YES] = 1e18;\\n _odds[OUTCOME_NO] = 49e18;\\n }\\n}\\n\",\"keccak256\":\"0x6a6d5b95f52a895fd1bffcdbd0e5a5f4343c085bf7ae8309eb56951f5b50e2ef\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n HasSpreadMarket(Spread, InvalidName)\\n HasOverUnderMarket(OverUnder, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x0d4c083d82b07c94a03831f3b79e9cdc1f6016c3532199b03cbd7d81b7d2a757\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252600781526611dc9bdd5c195960ca1b60208083019182528351808501909452600384526215109160ea1b9084015281519192916200005c916000916200007b565b508051620000729060019060208401906200007b565b50505062000127565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000b35760008555620000fe565b82601f10620000ce57805160ff1916838001178555620000fe565b82800160010185558215620000fe579182015b82811115620000fe578251825591602001919060010190620000e1565b506200010c92915062000110565b5090565b5b808211156200010c576000815560010162000111565b61232080620001376000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611928565b6100bc565b604051610074949392919061219a565b60405180910390f35b6100856100f5565b6040516100749190612187565b610085610183565b6100ad6100a8366004611982565b6101dd565b6040516100749392919061205c565b6100c461145f565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b61020661145f565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c611477565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114ce565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac0565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f7565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611c32565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611c32565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611c32565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611c32565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f791906119f9565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068891906119f9565b610c42565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611c32565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b0316638f23b3266040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611c32565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051633037faf160e01b81526000199094019360009081906001600160a01b038b1690633037faf190610864908990600401612259565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611a79565b915091506108c6828b610d4f565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b610911611477565b6040516333ad819560e21b81526000906001600160a01b0387169063ceb6065490610940908690600401612259565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611a47565b905060008160400151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611543565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886604001518581518110610a1257fe5b6020026020010151610dc5565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b508383526020808301519084015281516101008401906004811115610a5f57fe5b90816004811115610a6c57fe5b9052506040830181905260c080830151908401526080820151610a9490889088908890610dc5565b60808401525060a080820151908301526060808201519083015260e09081015190820152949350505050565b610ac86114ce565b6040516333ad819560e21b81526000906001600160a01b0386169063ceb6065490610af7908690600401612259565b60006040518083038186803b158015610b0f57600080fd5b505afa158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611a47565b905060008160400151516001600160401b0381118015610b6a57600080fd5b50604051908082528060200260200182016040528015610ba457816020015b610b9161159b565b815260200190600190039081610b895790505b50905060005b8151811015610bf457610bd5878785604001518481518110610bc857fe5b6020026020010151610f37565b828281518110610be157fe5b6020908102919091010152600101610baa565b50838352604083018190526080820151610c119087908790610f37565b6060840152815160208401906004811115610c2857fe5b90816004811115610c3557fe5b8152505050509392505050565b610c4a6115c7565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc99190810190611a15565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d429190611c4a565b60ff166040820152919050565b6000805b836040015151811015610d9f57600084604001518281518110610d7257fe5b60200260200101519050610d868482610ffb565b15610d9657600192505050610dbf565b50600101610d53565b50610dae828460800151610ffb565b15610dbb57506001610dbf565b5060005b92915050565b610dcd611543565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610dfc908690600401612259565b60006040518083038186803b158015610e1457600080fd5b505afa158015610e28573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e509190810190611abd565b6001600160a01b0387168352602083018490529050610e7086868561111d565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ea79088908a90889060040161214a565b60a06040518083038186803b158015610ebf57600080fd5b505afa158015610ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190611bc6565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f3f61159b565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f6e908690600401612259565b60006040518083038186803b158015610f8657600080fd5b505afa158015610f9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc29190810190611abd565b6001600160a01b0380871684526020840185905260408201511660608401529050610fee85858561111d565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b815260040161102a9190612259565b60006040518083038186803b15801561104257600080fd5b505afa158015611056573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107e9190810190611abd565b60408101519091506001600160a01b031661109d576001915050610dbf565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110dc57600080fd5b505afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111149190611c32565b11949350505050565b6111256115f1565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290611156908890879060040161216e565b60206040518083038186803b15801561116e57600080fd5b505afa158015611182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a691906119f9565b90506001600160a01b0381166111bc5750611458565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111ff57600080fd5b505afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190611c32565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de3599061126a908890879060040161216e565b60206040518083038186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190611c32565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112ed908890879060040161216e565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906119c7565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd90611376908890879060040161216e565b60006040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ca91908101906119c7565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113fd908890879060040161216e565b60006040518083038186803b15801561141557600080fd5b505afa158015611429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261145191908101906119c7565b6060830152505b9392505050565b60405180602001604052806114726114f7565b905290565b604051806101200160405280600081526020016060815260200160608152602001606081526020016114a7611543565b81526020016060815260200160008152602001606081526020016000600481111561147257fe5b60408051608081019091526000808252602082019081526020016060815260200161147261159b565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115366115c7565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115636115f1565b8152602001611570611630565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115ba6115f1565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161166c816122d2565b919050565b600082601f830112611681578081fd5b8151602061169661169183612285565b612262565b82815281810190858301838502870184018810156116b2578586fd5b855b858110156116d95781516116c7816122d2565b845292840192908401906001016116b4565b5090979650505050505050565b600082601f8301126116f6578081fd5b8151602061170661169183612285565b82815281810190858301855b858110156116d957611729898684518b01016117b4565b84529284019290840190600101611712565b600082601f83011261174b578081fd5b8151602061175b61169183612285565b8281528181019085830183850287018401881015611777578586fd5b855b858110156116d957815184529284019290840190600101611779565b8051801515811461166c57600080fd5b80516005811061166c57600080fd5b600082601f8301126117c4578081fd5b81516001600160401b038111156117d757fe5b6117ea601f8201601f1916602001612262565b8181528460208386010111156117fe578283fd5b61180f8260208301602087016122a2565b949350505050565b600061012080838503121561182a578182fd5b61183381612262565b91505061183f826117a5565b815260208201516001600160401b038082111561185b57600080fd5b611867858386016117b4565b6020840152604084015191508082111561188057600080fd5b61188c8583860161173b565b604084015260608401519150808211156118a557600080fd5b6118b1858386016116e6565b60608401526080840151608084015260a08401519150808211156118d457600080fd5b6118e0858386016117b4565b60a084015260c084015160c084015260e084015191508082111561190357600080fd5b50611910848285016117b4565b60e08301525061010080830151818301525092915050565b600080600080600060a0868803121561193f578081fd5b853561194a816122d2565b9450602086013561195a816122d2565b9350604086013561196a816122d2565b94979396509394606081013594506080013592915050565b60008060008060808587031215611997578182fd5b84356119a2816122d2565b935060208501356119b2816122d2565b93969395505050506040820135916060013590565b6000602082840312156119d8578081fd5b81516001600160401b038111156119ed578182fd5b61180f8482850161173b565b600060208284031215611a0a578081fd5b8151611458816122d2565b600060208284031215611a26578081fd5b81516001600160401b03811115611a3b578182fd5b61180f848285016117b4565b600060208284031215611a58578081fd5b81516001600160401b03811115611a6d578182fd5b61180f84828501611817565b60008060408385031215611a8b578182fd5b82516001600160401b03811115611aa0578283fd5b611aac85828601611817565b925050602083015190509250929050565b600060208284031215611ace578081fd5b81516001600160401b0380821115611ae4578283fd5b8184019150610160808387031215611afa578384fd5b611b0381612262565b9050611b0e83611661565b8152602083015182811115611b21578485fd5b611b2d87828601611671565b602083015250611b3f60408401611661565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611b95578586fd5b611ba18882870161173b565b8284015250506101409150611bb7828401611795565b91810191909152949350505050565b600060a08284031215611bd7578081fd5b60405160a081018181106001600160401b0382111715611bf357fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611c2660808401611795565b60808201529392505050565b600060208284031215611c43578081fd5b5051919050565b600060208284031215611c5b578081fd5b815160ff81168114611458578182fd5b6000815180845260208085019450808401835b83811015611ca35781516001600160a01b031687529582019590820190600101611c7e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611ce2848351611e96565b98850198935090840190600101611cca565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952815161012081518652868201518188880152611d4882880182611e96565b91505060408083015187830382890152611d628382611e06565b9250505060608083015187830382890152611d7d8382611cae565b9250505060808083015187830382890152611d988382611fba565b9250505060a08083015187830382890152611db38382611e96565b9250505060c080830151818801525060e08083015187830382890152611dd98382611e96565b92505050610100808301519250611df281880184611e88565b509986019994505090840190600101611d1d565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611e3a848351611fba565b98850198935090840190600101611e22565b6000815180845260208085019450808401835b83811015611ca357815187529582019590820190600101611e5f565b6001600160a01b03169052565b60058110611e9257fe5b9052565b60008151808452611eae8160208601602086016122a2565b601f01601f19169290920160200192915050565b600060018060a01b0380835116845260208301516020850152604083015160806040860152611ef46080860182611f0d565b9050816060850151166060860152809250505092915050565b600060018060a01b038251168352602082015160c06020850152611f3460c0850182611e4c565b905060408301518482036040860152611f4d8282611e4c565b91505060608301518482036060860152611f678282611e4c565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b6000610180611fca848451611e7b565b602083015160208501526040830151816040860152611feb82860182611f0d565b91505060608301516120006060860182611f88565b5060808301518482036101008601526120198282611c6b565b91505060a083015161012085015260c083015161203a610140860182611e7b565b5060e08301518482036101608601526120538282611e4c565b95945050505050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b8481101561212e57607f198a8403018652815187840181518552858201516120ac87870182611e88565b506040828101519086018a905280519182905260a08783028701810192908701918801908d5b8181101561210057609f198986030184526120ee858451611ec2565b945092890192918901916001016120d2565b5050505090890151848203858b01529061211a8183611ec2565b978601979450505090830190600101612082565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114586020830184611e96565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526122196101e0860182611e96565b905060408201516101c086015260c083015161016086015284810360208601526122438189611d01565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561227d57fe5b604052919050565b60006001600160401b0382111561229857fe5b5060209081020190565b60005b838110156122bd5781810151838201526020016122a5565b838111156122cc576000848401525b50505050565b6001600160a01b03811681146122e757600080fd5b5056fea26469706673582212203131739208a2c54614d5daaafc84d3bc0e05589986d9aada215b1248a8fb9b1364736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611928565b6100bc565b604051610074949392919061219a565b60405180910390f35b6100856100f5565b6040516100749190612187565b610085610183565b6100ad6100a8366004611982565b6101dd565b6040516100749392919061205c565b6100c461145f565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b61020661145f565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c611477565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114ce565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac0565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f7565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611c32565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611c32565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611c32565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611c32565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f791906119f9565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068891906119f9565b610c42565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611c32565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b0316638f23b3266040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611c32565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051633037faf160e01b81526000199094019360009081906001600160a01b038b1690633037faf190610864908990600401612259565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611a79565b915091506108c6828b610d4f565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b610911611477565b6040516333ad819560e21b81526000906001600160a01b0387169063ceb6065490610940908690600401612259565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611a47565b905060008160400151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611543565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886604001518581518110610a1257fe5b6020026020010151610dc5565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b508383526020808301519084015281516101008401906004811115610a5f57fe5b90816004811115610a6c57fe5b9052506040830181905260c080830151908401526080820151610a9490889088908890610dc5565b60808401525060a080820151908301526060808201519083015260e09081015190820152949350505050565b610ac86114ce565b6040516333ad819560e21b81526000906001600160a01b0386169063ceb6065490610af7908690600401612259565b60006040518083038186803b158015610b0f57600080fd5b505afa158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611a47565b905060008160400151516001600160401b0381118015610b6a57600080fd5b50604051908082528060200260200182016040528015610ba457816020015b610b9161159b565b815260200190600190039081610b895790505b50905060005b8151811015610bf457610bd5878785604001518481518110610bc857fe5b6020026020010151610f37565b828281518110610be157fe5b6020908102919091010152600101610baa565b50838352604083018190526080820151610c119087908790610f37565b6060840152815160208401906004811115610c2857fe5b90816004811115610c3557fe5b8152505050509392505050565b610c4a6115c7565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc99190810190611a15565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d429190611c4a565b60ff166040820152919050565b6000805b836040015151811015610d9f57600084604001518281518110610d7257fe5b60200260200101519050610d868482610ffb565b15610d9657600192505050610dbf565b50600101610d53565b50610dae828460800151610ffb565b15610dbb57506001610dbf565b5060005b92915050565b610dcd611543565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610dfc908690600401612259565b60006040518083038186803b158015610e1457600080fd5b505afa158015610e28573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e509190810190611abd565b6001600160a01b0387168352602083018490529050610e7086868561111d565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ea79088908a90889060040161214a565b60a06040518083038186803b158015610ebf57600080fd5b505afa158015610ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190611bc6565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f3f61159b565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f6e908690600401612259565b60006040518083038186803b158015610f8657600080fd5b505afa158015610f9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc29190810190611abd565b6001600160a01b0380871684526020840185905260408201511660608401529050610fee85858561111d565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b815260040161102a9190612259565b60006040518083038186803b15801561104257600080fd5b505afa158015611056573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107e9190810190611abd565b60408101519091506001600160a01b031661109d576001915050610dbf565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110dc57600080fd5b505afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111149190611c32565b11949350505050565b6111256115f1565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290611156908890879060040161216e565b60206040518083038186803b15801561116e57600080fd5b505afa158015611182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a691906119f9565b90506001600160a01b0381166111bc5750611458565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111ff57600080fd5b505afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190611c32565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de3599061126a908890879060040161216e565b60206040518083038186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190611c32565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112ed908890879060040161216e565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906119c7565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd90611376908890879060040161216e565b60006040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ca91908101906119c7565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113fd908890879060040161216e565b60006040518083038186803b15801561141557600080fd5b505afa158015611429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261145191908101906119c7565b6060830152505b9392505050565b60405180602001604052806114726114f7565b905290565b604051806101200160405280600081526020016060815260200160608152602001606081526020016114a7611543565b81526020016060815260200160008152602001606081526020016000600481111561147257fe5b60408051608081019091526000808252602082019081526020016060815260200161147261159b565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115366115c7565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115636115f1565b8152602001611570611630565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115ba6115f1565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161166c816122d2565b919050565b600082601f830112611681578081fd5b8151602061169661169183612285565b612262565b82815281810190858301838502870184018810156116b2578586fd5b855b858110156116d95781516116c7816122d2565b845292840192908401906001016116b4565b5090979650505050505050565b600082601f8301126116f6578081fd5b8151602061170661169183612285565b82815281810190858301855b858110156116d957611729898684518b01016117b4565b84529284019290840190600101611712565b600082601f83011261174b578081fd5b8151602061175b61169183612285565b8281528181019085830183850287018401881015611777578586fd5b855b858110156116d957815184529284019290840190600101611779565b8051801515811461166c57600080fd5b80516005811061166c57600080fd5b600082601f8301126117c4578081fd5b81516001600160401b038111156117d757fe5b6117ea601f8201601f1916602001612262565b8181528460208386010111156117fe578283fd5b61180f8260208301602087016122a2565b949350505050565b600061012080838503121561182a578182fd5b61183381612262565b91505061183f826117a5565b815260208201516001600160401b038082111561185b57600080fd5b611867858386016117b4565b6020840152604084015191508082111561188057600080fd5b61188c8583860161173b565b604084015260608401519150808211156118a557600080fd5b6118b1858386016116e6565b60608401526080840151608084015260a08401519150808211156118d457600080fd5b6118e0858386016117b4565b60a084015260c084015160c084015260e084015191508082111561190357600080fd5b50611910848285016117b4565b60e08301525061010080830151818301525092915050565b600080600080600060a0868803121561193f578081fd5b853561194a816122d2565b9450602086013561195a816122d2565b9350604086013561196a816122d2565b94979396509394606081013594506080013592915050565b60008060008060808587031215611997578182fd5b84356119a2816122d2565b935060208501356119b2816122d2565b93969395505050506040820135916060013590565b6000602082840312156119d8578081fd5b81516001600160401b038111156119ed578182fd5b61180f8482850161173b565b600060208284031215611a0a578081fd5b8151611458816122d2565b600060208284031215611a26578081fd5b81516001600160401b03811115611a3b578182fd5b61180f848285016117b4565b600060208284031215611a58578081fd5b81516001600160401b03811115611a6d578182fd5b61180f84828501611817565b60008060408385031215611a8b578182fd5b82516001600160401b03811115611aa0578283fd5b611aac85828601611817565b925050602083015190509250929050565b600060208284031215611ace578081fd5b81516001600160401b0380821115611ae4578283fd5b8184019150610160808387031215611afa578384fd5b611b0381612262565b9050611b0e83611661565b8152602083015182811115611b21578485fd5b611b2d87828601611671565b602083015250611b3f60408401611661565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611b95578586fd5b611ba18882870161173b565b8284015250506101409150611bb7828401611795565b91810191909152949350505050565b600060a08284031215611bd7578081fd5b60405160a081018181106001600160401b0382111715611bf357fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611c2660808401611795565b60808201529392505050565b600060208284031215611c43578081fd5b5051919050565b600060208284031215611c5b578081fd5b815160ff81168114611458578182fd5b6000815180845260208085019450808401835b83811015611ca35781516001600160a01b031687529582019590820190600101611c7e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611ce2848351611e96565b98850198935090840190600101611cca565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952815161012081518652868201518188880152611d4882880182611e96565b91505060408083015187830382890152611d628382611e06565b9250505060608083015187830382890152611d7d8382611cae565b9250505060808083015187830382890152611d988382611fba565b9250505060a08083015187830382890152611db38382611e96565b9250505060c080830151818801525060e08083015187830382890152611dd98382611e96565b92505050610100808301519250611df281880184611e88565b509986019994505090840190600101611d1d565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611e3a848351611fba565b98850198935090840190600101611e22565b6000815180845260208085019450808401835b83811015611ca357815187529582019590820190600101611e5f565b6001600160a01b03169052565b60058110611e9257fe5b9052565b60008151808452611eae8160208601602086016122a2565b601f01601f19169290920160200192915050565b600060018060a01b0380835116845260208301516020850152604083015160806040860152611ef46080860182611f0d565b9050816060850151166060860152809250505092915050565b600060018060a01b038251168352602082015160c06020850152611f3460c0850182611e4c565b905060408301518482036040860152611f4d8282611e4c565b91505060608301518482036060860152611f678282611e4c565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b6000610180611fca848451611e7b565b602083015160208501526040830151816040860152611feb82860182611f0d565b91505060608301516120006060860182611f88565b5060808301518482036101008601526120198282611c6b565b91505060a083015161012085015260c083015161203a610140860182611e7b565b5060e08301518482036101608601526120538282611e4c565b95945050505050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b8481101561212e57607f198a8403018652815187840181518552858201516120ac87870182611e88565b506040828101519086018a905280519182905260a08783028701810192908701918801908d5b8181101561210057609f198986030184526120ee858451611ec2565b945092890192918901916001016120d2565b5050505090890151848203858b01529061211a8183611ec2565b978601979450505090830190600101612082565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114586020830184611e96565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526122196101e0860182611e96565b905060408201516101c086015260c083015161016086015284810360208601526122438189611d01565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561227d57fe5b604052919050565b60006001600160401b0382111561229857fe5b5060209081020190565b60005b838110156122bd5781810151838201526020016122a5565b838111156122cc576000848401525b50505050565b6001600160a01b03811681146122e757600080fd5b5056fea26469706673582212203131739208a2c54614d5daaafc84d3bc0e05589986d9aada215b1248a8fb9b1364736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle\",\"name\":\"invalidMarket\",\"type\":\"tuple\"}],\"internalType\":\"struct GroupFetcher.DynamicGroupBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestGroupIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct GroupFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle\",\"name\":\"invalidMarket\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"}],\"internalType\":\"struct GroupFetcher.StaticGroupBundle[]\",\"name\":\"_groupBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestGroupIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/GroupFetcher.sol\":\"GroupedFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/GroupFetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Fetcher.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\n\\nabstract contract GroupFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticGroupBundle {\\n uint256 id;\\n string name;\\n StaticMarketBundle[] markets;\\n string[] marketNames;\\n StaticMarketBundle invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n // Dynamics\\n Grouped.GroupStatus status;\\n }\\n\\n struct DynamicGroupBundle {\\n uint256 id;\\n Grouped.GroupStatus status;\\n DynamicMarketBundle[] markets;\\n DynamicMarketBundle invalidMarket;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticGroupBundle[] memory _groupBundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_groupBundles, _lowestGroupIndex) = buildStaticGroupBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicGroupBundle[] memory _bundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestGroupIndex) = buildDynamicGroupBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new StaticGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticGroupBundle(_marketFactory, _ammFactory, _masterChef, _groupIds[i]);\\n }\\n }\\n\\n function buildDynamicGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new DynamicGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicGroupBundle(_marketFactory, _ammFactory, _groupIds[i]);\\n }\\n }\\n\\n function buildStaticGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _groupId\\n ) internal view returns (StaticGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.name = _group.name;\\n _bundle.status = _group.status;\\n _bundle.markets = _markets;\\n _bundle.endTime = _group.endTime;\\n _bundle.invalidMarket = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.invalidMarket\\n );\\n _bundle.invalidMarketName = _group.invalidMarketName;\\n _bundle.marketNames = _group.marketNames;\\n _bundle.category = _group.category;\\n }\\n\\n function buildDynamicGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _groupId\\n ) internal view returns (DynamicGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.markets = _markets;\\n _bundle.invalidMarket = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.invalidMarket\\n );\\n _bundle.status = _group.status;\\n }\\n\\n // Starts from the end of the groups list because newer groups are more interesting.\\n // _offset is skipping all groups, not just interesting groups\\n function listOfInterestingGroups(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingGroupIds, uint256 _groupIndex) {\\n _interestingGroupIds = new uint256[](_total);\\n\\n uint256 _groupCount = Grouped(_marketFactory).groupCount();\\n\\n // No groups so return nothing. (needed to avoid integer underflow below)\\n if (_groupCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _groupCount;\\n\\n // No remaining groups so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedGroups = 0;\\n _groupIndex = _max - _offset;\\n while (true) {\\n if (_collectedGroups >= _total) break;\\n if (_groupIndex == 0) break;\\n\\n _groupIndex--; // starts out one too high, so this works\\n\\n (Grouped.MarketGroup memory _group, uint256 _groupId) =\\n Grouped(_marketFactory).getGroupByIndex(_groupIndex);\\n\\n if (isGroupInteresting(_group, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingGroupIds[_collectedGroups] = _groupId;\\n _collectedGroups++;\\n }\\n }\\n\\n if (_total > _collectedGroups) {\\n assembly {\\n // shortens array\\n mstore(_interestingGroupIds, _collectedGroups)\\n }\\n }\\n }\\n\\n function isGroupInteresting(Grouped.MarketGroup memory _group, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _group.markets.length; i++) {\\n uint256 _marketId = _group.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n if (openOrHasWinningShares(_marketFactory, _group.invalidMarket)) {\\n return true;\\n }\\n\\n return false;\\n }\\n}\\n\\ncontract GroupedFetcher is GroupFetcher {\\n constructor() Fetcher(\\\"Grouped\\\", \\\"TBD\\\") {}\\n}\\n\",\"keccak256\":\"0xd8cb93eee1737373d56fd149e2bbbf81a3b1b0f6516bfc217acc402105474cfc\",\"license\":\"MIT\"},\"contracts/turbo/Grouped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./GroupFetcher.sol\\\";\\n\\nabstract contract Grouped is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds {\\n event GroupCreated(uint256 indexed id, uint256 endTime, uint256 invalidMarketId, string invalidMarketName);\\n event GroupMarketAdded(uint256 indexed groupId, uint256 marketId, string marketName);\\n event GroupFinalizing(uint256 indexed groupId, uint256 winningMarketIndex);\\n event GroupResolved(uint256 indexed id, bool valid);\\n\\n enum GroupStatus {Unknown, Scheduled, Finalizing, Final, Invalid}\\n\\n struct MarketGroup {\\n GroupStatus status;\\n string name;\\n uint256[] markets;\\n string[] marketNames;\\n uint256 invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n uint256 winningMarketIndex; // ignore when status is Scheduled. MAX_UINT is invalid\\n }\\n // GroupId => MarketGroup\\n mapping(uint256 => MarketGroup) public marketGroups;\\n uint256[] public listOfMarketGroups;\\n\\n // For regular markets, YES means the team won and NO means the team did not win.\\n // For the invalid market, YES means none of the teams won and NO means a team won.\\n uint256 constant OUTCOME_NO = 0;\\n uint256 constant OUTCOME_YES = 1;\\n\\n uint256 constant MAX_UINT = 2**256 - 1;\\n\\n function groupCount() public view returns (uint256) {\\n return listOfMarketGroups.length;\\n }\\n\\n function getGroup(uint256 _groupId) public view returns (MarketGroup memory) {\\n return marketGroups[_groupId];\\n }\\n\\n function getGroupByIndex(uint256 _index) public view returns (MarketGroup memory _group, uint256 _groupId) {\\n _groupId = listOfMarketGroups[_index];\\n _group = getGroup(_groupId);\\n }\\n\\n function startCreatingMarketGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n uint256 _endTime,\\n string memory _invalidMarketName,\\n string memory _category\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Unknown, \\\"group exists\\\");\\n\\n listOfMarketGroups.push(_groupId);\\n marketGroups[_groupId].status = GroupStatus.Scheduled;\\n marketGroups[_groupId].name = _groupName;\\n marketGroups[_groupId].endTime = _endTime;\\n marketGroups[_groupId].category = _category;\\n\\n uint256 _invalidMarket = startMarket(msg.sender, buildOutcomesNames(_invalidMarketName), invalidOdds(), true);\\n marketGroups[_groupId].invalidMarket = _invalidMarket;\\n marketGroups[_groupId].invalidMarketName = _invalidMarketName;\\n\\n emit GroupCreated(_groupId, _endTime, _invalidMarket, _invalidMarketName);\\n emit GroupMarketAdded(_groupId, _invalidMarket, _invalidMarketName);\\n }\\n\\n function addMarketToMarketGroup(\\n uint256 _groupId,\\n string memory _marketName,\\n uint256[] memory _odds\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Scheduled, \\\"group must be Scheduled\\\");\\n\\n uint256 _marketId = startMarket(msg.sender, buildOutcomesNames(_marketName), _odds, true);\\n marketGroups[_groupId].markets.push(_marketId);\\n marketGroups[_groupId].marketNames.push(_marketName);\\n emit GroupMarketAdded(_groupId, _marketId, _marketName);\\n }\\n\\n // Use MAX_UINT for _winningMarketIndex to indicate INVALID\\n function startResolvingMarketGroup(uint256 _groupId, uint256 _winningMarketIndex) internal {\\n bool _isInvalid = _winningMarketIndex == MAX_UINT;\\n MarketGroup memory _group = marketGroups[_groupId];\\n\\n require(_group.status == GroupStatus.Scheduled, \\\"group not Scheduled\\\");\\n\\n resolveInvalidMarket(_group, _isInvalid);\\n marketGroups[_groupId].status = GroupStatus.Finalizing;\\n marketGroups[_groupId].winningMarketIndex = _winningMarketIndex;\\n emit GroupFinalizing(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveFinalizingGroupMarket(uint256 _groupId, uint256 _marketIndex) internal {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing, \\\"must be finalizing\\\");\\n\\n uint256 _marketId = _group.markets[_marketIndex];\\n bool _wins = _marketIndex == _group.winningMarketIndex;\\n resolveGroupMarket(_marketId, _wins);\\n }\\n\\n function finalizeMarketGroup(uint256 _groupId) internal {\\n MarketGroup storage _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n bool _valid = _group.winningMarketIndex != MAX_UINT;\\n\\n _group.status = _valid ? GroupStatus.Final : GroupStatus.Invalid;\\n\\n emit GroupResolved(_groupId, _valid);\\n }\\n\\n function resolveGroupMarket(uint256 _marketId, bool _wins) internal {\\n uint256 _winningOutcome = _wins ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_marketId, _winningOutcome);\\n }\\n\\n function resolveInvalidMarket(MarketGroup memory _group, bool _invalid) private {\\n uint256 _outcomeIndex = _invalid ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_group.invalidMarket, _outcomeIndex);\\n }\\n\\n function buildOutcomesNames(string memory _marketName) internal pure returns (string[] memory _names) {\\n _names = new string[](2);\\n _names[OUTCOME_NO] = string(abi.encodePacked(\\\"NO - \\\", _marketName));\\n _names[OUTCOME_YES] = string(abi.encodePacked(\\\"YES - \\\", _marketName));\\n }\\n\\n function invalidOdds() private pure returns (uint256[] memory _odds) {\\n _odds = new uint256[](2);\\n _odds[OUTCOME_YES] = 1e18;\\n _odds[OUTCOME_NO] = 49e18;\\n }\\n}\\n\",\"keccak256\":\"0x6a6d5b95f52a895fd1bffcdbd0e5a5f4343c085bf7ae8309eb56951f5b50e2ef\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant Spread = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.5.0\\\")\\n ManagedByLink(_linkNode)\\n HasSpreadMarket(Spread, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n makeLine(_homeSpread),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\\n internal\\n returns (uint256[] memory _marketIds)\\n {\\n _marketIds = new uint256[](1);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n }\\n\\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\\n _line = build1Line();\\n _line[0] = addHalfPoint(_homeSpread);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x2187210295b55bd841518dc83cb592ef7365c4d7ba4f38895865e4d26ccefe35\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604080518082018252600781526611dc9bdd5c195960ca1b60208083019182528351808501909452600384526215109160ea1b9084015281519192916200005c916000916200007b565b508051620000729060019060208401906200007b565b50505062000127565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000b35760008555620000fe565b82601f10620000ce57805160ff1916838001178555620000fe565b82800160010185558215620000fe579182015b82811115620000fe578251825591602001919060010190620000e1565b506200010c92915062000110565b5090565b5b808211156200010c576000815560010162000111565b61232080620001376000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611928565b6100bc565b604051610074949392919061219a565b60405180910390f35b6100856100f5565b6040516100749190612187565b610085610183565b6100ad6100a8366004611982565b6101dd565b6040516100749392919061205c565b6100c461145f565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b61020661145f565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c611477565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114ce565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac0565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f7565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611c32565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611c32565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611c32565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611c32565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f791906119f9565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068891906119f9565b610c42565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611c32565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b0316638f23b3266040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611c32565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051633037faf160e01b81526000199094019360009081906001600160a01b038b1690633037faf190610864908990600401612259565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611a79565b915091506108c6828b610d4f565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b610911611477565b6040516333ad819560e21b81526000906001600160a01b0387169063ceb6065490610940908690600401612259565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611a47565b905060008160400151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611543565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886604001518581518110610a1257fe5b6020026020010151610dc5565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b508383526020808301519084015281516101008401906004811115610a5f57fe5b90816004811115610a6c57fe5b9052506040830181905260c080830151908401526080820151610a9490889088908890610dc5565b60808401525060a080820151908301526060808201519083015260e09081015190820152949350505050565b610ac86114ce565b6040516333ad819560e21b81526000906001600160a01b0386169063ceb6065490610af7908690600401612259565b60006040518083038186803b158015610b0f57600080fd5b505afa158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611a47565b905060008160400151516001600160401b0381118015610b6a57600080fd5b50604051908082528060200260200182016040528015610ba457816020015b610b9161159b565b815260200190600190039081610b895790505b50905060005b8151811015610bf457610bd5878785604001518481518110610bc857fe5b6020026020010151610f37565b828281518110610be157fe5b6020908102919091010152600101610baa565b50838352604083018190526080820151610c119087908790610f37565b6060840152815160208401906004811115610c2857fe5b90816004811115610c3557fe5b8152505050509392505050565b610c4a6115c7565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc99190810190611a15565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d429190611c4a565b60ff166040820152919050565b6000805b836040015151811015610d9f57600084604001518281518110610d7257fe5b60200260200101519050610d868482610ffb565b15610d9657600192505050610dbf565b50600101610d53565b50610dae828460800151610ffb565b15610dbb57506001610dbf565b5060005b92915050565b610dcd611543565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610dfc908690600401612259565b60006040518083038186803b158015610e1457600080fd5b505afa158015610e28573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e509190810190611abd565b6001600160a01b0387168352602083018490529050610e7086868561111d565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ea79088908a90889060040161214a565b60a06040518083038186803b158015610ebf57600080fd5b505afa158015610ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190611bc6565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f3f61159b565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f6e908690600401612259565b60006040518083038186803b158015610f8657600080fd5b505afa158015610f9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc29190810190611abd565b6001600160a01b0380871684526020840185905260408201511660608401529050610fee85858561111d565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b815260040161102a9190612259565b60006040518083038186803b15801561104257600080fd5b505afa158015611056573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107e9190810190611abd565b60408101519091506001600160a01b031661109d576001915050610dbf565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110dc57600080fd5b505afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111149190611c32565b11949350505050565b6111256115f1565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290611156908890879060040161216e565b60206040518083038186803b15801561116e57600080fd5b505afa158015611182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a691906119f9565b90506001600160a01b0381166111bc5750611458565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111ff57600080fd5b505afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190611c32565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de3599061126a908890879060040161216e565b60206040518083038186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190611c32565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112ed908890879060040161216e565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906119c7565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd90611376908890879060040161216e565b60006040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ca91908101906119c7565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113fd908890879060040161216e565b60006040518083038186803b15801561141557600080fd5b505afa158015611429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261145191908101906119c7565b6060830152505b9392505050565b60405180602001604052806114726114f7565b905290565b604051806101200160405280600081526020016060815260200160608152602001606081526020016114a7611543565b81526020016060815260200160008152602001606081526020016000600481111561147257fe5b60408051608081019091526000808252602082019081526020016060815260200161147261159b565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115366115c7565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115636115f1565b8152602001611570611630565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115ba6115f1565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161166c816122d2565b919050565b600082601f830112611681578081fd5b8151602061169661169183612285565b612262565b82815281810190858301838502870184018810156116b2578586fd5b855b858110156116d95781516116c7816122d2565b845292840192908401906001016116b4565b5090979650505050505050565b600082601f8301126116f6578081fd5b8151602061170661169183612285565b82815281810190858301855b858110156116d957611729898684518b01016117b4565b84529284019290840190600101611712565b600082601f83011261174b578081fd5b8151602061175b61169183612285565b8281528181019085830183850287018401881015611777578586fd5b855b858110156116d957815184529284019290840190600101611779565b8051801515811461166c57600080fd5b80516005811061166c57600080fd5b600082601f8301126117c4578081fd5b81516001600160401b038111156117d757fe5b6117ea601f8201601f1916602001612262565b8181528460208386010111156117fe578283fd5b61180f8260208301602087016122a2565b949350505050565b600061012080838503121561182a578182fd5b61183381612262565b91505061183f826117a5565b815260208201516001600160401b038082111561185b57600080fd5b611867858386016117b4565b6020840152604084015191508082111561188057600080fd5b61188c8583860161173b565b604084015260608401519150808211156118a557600080fd5b6118b1858386016116e6565b60608401526080840151608084015260a08401519150808211156118d457600080fd5b6118e0858386016117b4565b60a084015260c084015160c084015260e084015191508082111561190357600080fd5b50611910848285016117b4565b60e08301525061010080830151818301525092915050565b600080600080600060a0868803121561193f578081fd5b853561194a816122d2565b9450602086013561195a816122d2565b9350604086013561196a816122d2565b94979396509394606081013594506080013592915050565b60008060008060808587031215611997578182fd5b84356119a2816122d2565b935060208501356119b2816122d2565b93969395505050506040820135916060013590565b6000602082840312156119d8578081fd5b81516001600160401b038111156119ed578182fd5b61180f8482850161173b565b600060208284031215611a0a578081fd5b8151611458816122d2565b600060208284031215611a26578081fd5b81516001600160401b03811115611a3b578182fd5b61180f848285016117b4565b600060208284031215611a58578081fd5b81516001600160401b03811115611a6d578182fd5b61180f84828501611817565b60008060408385031215611a8b578182fd5b82516001600160401b03811115611aa0578283fd5b611aac85828601611817565b925050602083015190509250929050565b600060208284031215611ace578081fd5b81516001600160401b0380821115611ae4578283fd5b8184019150610160808387031215611afa578384fd5b611b0381612262565b9050611b0e83611661565b8152602083015182811115611b21578485fd5b611b2d87828601611671565b602083015250611b3f60408401611661565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611b95578586fd5b611ba18882870161173b565b8284015250506101409150611bb7828401611795565b91810191909152949350505050565b600060a08284031215611bd7578081fd5b60405160a081018181106001600160401b0382111715611bf357fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611c2660808401611795565b60808201529392505050565b600060208284031215611c43578081fd5b5051919050565b600060208284031215611c5b578081fd5b815160ff81168114611458578182fd5b6000815180845260208085019450808401835b83811015611ca35781516001600160a01b031687529582019590820190600101611c7e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611ce2848351611e96565b98850198935090840190600101611cca565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952815161012081518652868201518188880152611d4882880182611e96565b91505060408083015187830382890152611d628382611e06565b9250505060608083015187830382890152611d7d8382611cae565b9250505060808083015187830382890152611d988382611fba565b9250505060a08083015187830382890152611db38382611e96565b9250505060c080830151818801525060e08083015187830382890152611dd98382611e96565b92505050610100808301519250611df281880184611e88565b509986019994505090840190600101611d1d565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611e3a848351611fba565b98850198935090840190600101611e22565b6000815180845260208085019450808401835b83811015611ca357815187529582019590820190600101611e5f565b6001600160a01b03169052565b60058110611e9257fe5b9052565b60008151808452611eae8160208601602086016122a2565b601f01601f19169290920160200192915050565b600060018060a01b0380835116845260208301516020850152604083015160806040860152611ef46080860182611f0d565b9050816060850151166060860152809250505092915050565b600060018060a01b038251168352602082015160c06020850152611f3460c0850182611e4c565b905060408301518482036040860152611f4d8282611e4c565b91505060608301518482036060860152611f678282611e4c565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b6000610180611fca848451611e7b565b602083015160208501526040830151816040860152611feb82860182611f0d565b91505060608301516120006060860182611f88565b5060808301518482036101008601526120198282611c6b565b91505060a083015161012085015260c083015161203a610140860182611e7b565b5060e08301518482036101608601526120538282611e4c565b95945050505050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b8481101561212e57607f198a8403018652815187840181518552858201516120ac87870182611e88565b506040828101519086018a905280519182905260a08783028701810192908701918801908d5b8181101561210057609f198986030184526120ee858451611ec2565b945092890192918901916001016120d2565b5050505090890151848203858b01529061211a8183611ec2565b978601979450505090830190600101612082565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114586020830184611e96565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526122196101e0860182611e96565b905060408201516101c086015260c083015161016086015284810360208601526122438189611d01565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561227d57fe5b604052919050565b60006001600160401b0382111561229857fe5b5060209081020190565b60005b838110156122bd5781810151838201526020016122a5565b838111156122cc576000848401525b50505050565b6001600160a01b03811681146122e757600080fd5b5056fea2646970667358221220e7b1d4e1724d6e5fbd6f6ac7d5935c988d4350a97f1632b4e66ae111e8d7c13a64736f6c63430007060033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f366004611928565b6100bc565b604051610074949392919061219a565b60405180910390f35b6100856100f5565b6040516100749190612187565b610085610183565b6100ad6100a8366004611982565b6101dd565b6040516100749392919061205c565b6100c461145f565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b61020661145f565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c611477565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114ce565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac0565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f7565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611c32565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611c32565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611c32565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611c32565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f791906119f9565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068891906119f9565b610c42565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611c32565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b0316638f23b3266040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611c32565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051633037faf160e01b81526000199094019360009081906001600160a01b038b1690633037faf190610864908990600401612259565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611a79565b915091506108c6828b610d4f565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b610911611477565b6040516333ad819560e21b81526000906001600160a01b0387169063ceb6065490610940908690600401612259565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611a47565b905060008160400151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611543565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886604001518581518110610a1257fe5b6020026020010151610dc5565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b508383526020808301519084015281516101008401906004811115610a5f57fe5b90816004811115610a6c57fe5b9052506040830181905260c080830151908401526080820151610a9490889088908890610dc5565b60808401525060a080820151908301526060808201519083015260e09081015190820152949350505050565b610ac86114ce565b6040516333ad819560e21b81526000906001600160a01b0386169063ceb6065490610af7908690600401612259565b60006040518083038186803b158015610b0f57600080fd5b505afa158015610b23573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b4b9190810190611a47565b905060008160400151516001600160401b0381118015610b6a57600080fd5b50604051908082528060200260200182016040528015610ba457816020015b610b9161159b565b815260200190600190039081610b895790505b50905060005b8151811015610bf457610bd5878785604001518481518110610bc857fe5b6020026020010151610f37565b828281518110610be157fe5b6020908102919091010152600101610baa565b50838352604083018190526080820151610c119087908790610f37565b6060840152815160208401906004811115610c2857fe5b90816004811115610c3557fe5b8152505050509392505050565b610c4a6115c7565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8d57600080fd5b505afa158015610ca1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cc99190810190611a15565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0a57600080fd5b505afa158015610d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d429190611c4a565b60ff166040820152919050565b6000805b836040015151811015610d9f57600084604001518281518110610d7257fe5b60200260200101519050610d868482610ffb565b15610d9657600192505050610dbf565b50600101610d53565b50610dae828460800151610ffb565b15610dbb57506001610dbf565b5060005b92915050565b610dcd611543565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610dfc908690600401612259565b60006040518083038186803b158015610e1457600080fd5b505afa158015610e28573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e509190810190611abd565b6001600160a01b0387168352602083018490529050610e7086868561111d565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610ea79088908a90889060040161214a565b60a06040518083038186803b158015610ebf57600080fd5b505afa158015610ed3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef79190611bc6565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f3f61159b565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f6e908690600401612259565b60006040518083038186803b158015610f8657600080fd5b505afa158015610f9a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc29190810190611abd565b6001600160a01b0380871684526020840185905260408201511660608401529050610fee85858561111d565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b815260040161102a9190612259565b60006040518083038186803b15801561104257600080fd5b505afa158015611056573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261107e9190810190611abd565b60408101519091506001600160a01b031661109d576001915050610dbf565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110dc57600080fd5b505afa1580156110f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111149190611c32565b11949350505050565b6111256115f1565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea290611156908890879060040161216e565b60206040518083038186803b15801561116e57600080fd5b505afa158015611182573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a691906119f9565b90506001600160a01b0381166111bc5750611458565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111ff57600080fd5b505afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112379190611c32565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de3599061126a908890879060040161216e565b60206040518083038186803b15801561128257600080fd5b505afa158015611296573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ba9190611c32565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112ed908890879060040161216e565b60006040518083038186803b15801561130557600080fd5b505afa158015611319573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261134191908101906119c7565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd90611376908890879060040161216e565b60006040518083038186803b15801561138e57600080fd5b505afa1580156113a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ca91908101906119c7565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113fd908890879060040161216e565b60006040518083038186803b15801561141557600080fd5b505afa158015611429573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261145191908101906119c7565b6060830152505b9392505050565b60405180602001604052806114726114f7565b905290565b604051806101200160405280600081526020016060815260200160608152602001606081526020016114a7611543565b81526020016060815260200160008152602001606081526020016000600481111561147257fe5b60408051608081019091526000808252602082019081526020016060815260200161147261159b565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115366115c7565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115636115f1565b8152602001611570611630565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115ba6115f1565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b805161166c816122d2565b919050565b600082601f830112611681578081fd5b8151602061169661169183612285565b612262565b82815281810190858301838502870184018810156116b2578586fd5b855b858110156116d95781516116c7816122d2565b845292840192908401906001016116b4565b5090979650505050505050565b600082601f8301126116f6578081fd5b8151602061170661169183612285565b82815281810190858301855b858110156116d957611729898684518b01016117b4565b84529284019290840190600101611712565b600082601f83011261174b578081fd5b8151602061175b61169183612285565b8281528181019085830183850287018401881015611777578586fd5b855b858110156116d957815184529284019290840190600101611779565b8051801515811461166c57600080fd5b80516005811061166c57600080fd5b600082601f8301126117c4578081fd5b81516001600160401b038111156117d757fe5b6117ea601f8201601f1916602001612262565b8181528460208386010111156117fe578283fd5b61180f8260208301602087016122a2565b949350505050565b600061012080838503121561182a578182fd5b61183381612262565b91505061183f826117a5565b815260208201516001600160401b038082111561185b57600080fd5b611867858386016117b4565b6020840152604084015191508082111561188057600080fd5b61188c8583860161173b565b604084015260608401519150808211156118a557600080fd5b6118b1858386016116e6565b60608401526080840151608084015260a08401519150808211156118d457600080fd5b6118e0858386016117b4565b60a084015260c084015160c084015260e084015191508082111561190357600080fd5b50611910848285016117b4565b60e08301525061010080830151818301525092915050565b600080600080600060a0868803121561193f578081fd5b853561194a816122d2565b9450602086013561195a816122d2565b9350604086013561196a816122d2565b94979396509394606081013594506080013592915050565b60008060008060808587031215611997578182fd5b84356119a2816122d2565b935060208501356119b2816122d2565b93969395505050506040820135916060013590565b6000602082840312156119d8578081fd5b81516001600160401b038111156119ed578182fd5b61180f8482850161173b565b600060208284031215611a0a578081fd5b8151611458816122d2565b600060208284031215611a26578081fd5b81516001600160401b03811115611a3b578182fd5b61180f848285016117b4565b600060208284031215611a58578081fd5b81516001600160401b03811115611a6d578182fd5b61180f84828501611817565b60008060408385031215611a8b578182fd5b82516001600160401b03811115611aa0578283fd5b611aac85828601611817565b925050602083015190509250929050565b600060208284031215611ace578081fd5b81516001600160401b0380821115611ae4578283fd5b8184019150610160808387031215611afa578384fd5b611b0381612262565b9050611b0e83611661565b8152602083015182811115611b21578485fd5b611b2d87828601611671565b602083015250611b3f60408401611661565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611b95578586fd5b611ba18882870161173b565b8284015250506101409150611bb7828401611795565b91810191909152949350505050565b600060a08284031215611bd7578081fd5b60405160a081018181106001600160401b0382111715611bf357fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611c2660808401611795565b60808201529392505050565b600060208284031215611c43578081fd5b5051919050565b600060208284031215611c5b578081fd5b815160ff81168114611458578182fd5b6000815180845260208085019450808401835b83811015611ca35781516001600160a01b031687529582019590820190600101611c7e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611ce2848351611e96565b98850198935090840190600101611cca565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952815161012081518652868201518188880152611d4882880182611e96565b91505060408083015187830382890152611d628382611e06565b9250505060608083015187830382890152611d7d8382611cae565b9250505060808083015187830382890152611d988382611fba565b9250505060a08083015187830382890152611db38382611e96565b9250505060c080830151818801525060e08083015187830382890152611dd98382611e96565b92505050610100808301519250611df281880184611e88565b509986019994505090840190600101611d1d565b6000815180845260208085018081965082840281019150828601855b85811015611cf4578284038952611e3a848351611fba565b98850198935090840190600101611e22565b6000815180845260208085019450808401835b83811015611ca357815187529582019590820190600101611e5f565b6001600160a01b03169052565b60058110611e9257fe5b9052565b60008151808452611eae8160208601602086016122a2565b601f01601f19169290920160200192915050565b600060018060a01b0380835116845260208301516020850152604083015160806040860152611ef46080860182611f0d565b9050816060850151166060860152809250505092915050565b600060018060a01b038251168352602082015160c06020850152611f3460c0850182611e4c565b905060408301518482036040860152611f4d8282611e4c565b91505060608301518482036060860152611f678282611e4c565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b6000610180611fca848451611e7b565b602083015160208501526040830151816040860152611feb82860182611f0d565b91505060608301516120006060860182611f88565b5060808301518482036101008601526120198282611c6b565b91505060a083015161012085015260c083015161203a610140860182611e7b565b5060e08301518482036101608601526120538282611e4c565b95945050505050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b8481101561212e57607f198a8403018652815187840181518552858201516120ac87870182611e88565b506040828101519086018a905280519182905260a08783028701810192908701918801908d5b8181101561210057609f198986030184526120ee858451611ec2565b945092890192918901916001016120d2565b5050505090890151848203858b01529061211a8183611ec2565b978601979450505090830190600101612082565b5050908701989098525050505060409091019190915250919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114586020830184611e96565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526122196101e0860182611e96565b905060408201516101c086015260c083015161016086015284810360208601526122438189611d01565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561227d57fe5b604052919050565b60006001600160401b0382111561229857fe5b5060209081020190565b60005b838110156122bd5781810151838201526020016122a5565b838111156122cc576000848401525b50505050565b6001600160a01b03811681146122e757600080fd5b5056fea2646970667358221220e7b1d4e1724d6e5fbd6f6ac7d5935c988d4350a97f1632b4e66ae111e8d7c13a64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/smart/deployments/maticMumbai/GroupedMarketFactoryV3.json b/packages/smart/deployments/maticMumbai/GroupedMarketFactoryV3.json index 0c64deaa3..c03c4e2c4 100644 --- a/packages/smart/deployments/maticMumbai/GroupedMarketFactoryV3.json +++ b/packages/smart/deployments/maticMumbai/GroupedMarketFactoryV3.json @@ -1,5 +1,5 @@ { - "address": "0xCd5b1d5EB5944dC7497dC37f68E406f3A5aB4178", + "address": "0xC844a28C66E0796321351a262cB87A5da5D3d8fa", "abi": [ { "inputs": [ @@ -1208,35 +1208,35 @@ "type": "function" } ], - "transactionHash": "0x837343537cdf41fa333f23e5c53e028529174442f29a55f6e151ad1957ccd30c", + "transactionHash": "0x203e6c24c67dd3d37a34ece54ef94825f32aecd0b82a197b8aecbcf0257e1c31", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0xCd5b1d5EB5944dC7497dC37f68E406f3A5aB4178", - "transactionIndex": 0, + "contractAddress": "0xC844a28C66E0796321351a262cB87A5da5D3d8fa", + "transactionIndex": 1, "gasUsed": "5104951", - "logsBloom": "0x00000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000040000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000010000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x8f4877311b1bf3829590fd66c0afd4bc24ed37db1d6a9223aa068b6db689e57d", - "transactionHash": "0x837343537cdf41fa333f23e5c53e028529174442f29a55f6e151ad1957ccd30c", + "logsBloom": "0x0000000000000000000000000000000000000000000020000000c000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", + "blockHash": "0x4411e21aec3649d84112d39278c207d369d34c4fccf6464b76e25195108aed6b", + "transactionHash": "0x203e6c24c67dd3d37a34ece54ef94825f32aecd0b82a197b8aecbcf0257e1c31", "logs": [ { - "transactionIndex": 0, - "blockNumber": 19809239, - "transactionHash": "0x837343537cdf41fa333f23e5c53e028529174442f29a55f6e151ad1957ccd30c", + "transactionIndex": 1, + "blockNumber": 20388727, + "transactionHash": "0x203e6c24c67dd3d37a34ece54ef94825f32aecd0b82a197b8aecbcf0257e1c31", "address": "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x000000000000000000000000cd5b1d5eb5944dc7497dc37f68e406f3a5ab4178", + "0x000000000000000000000000c844a28c66e0796321351a262cb87a5da5d3d8fa", "0x00000000000000000000000059ddfe9961e050bda1ed9bf9ccd009948036dd76" ], "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "logIndex": 0, - "blockHash": "0x8f4877311b1bf3829590fd66c0afd4bc24ed37db1d6a9223aa068b6db689e57d" + "logIndex": 2, + "blockHash": "0x4411e21aec3649d84112d39278c207d369d34c4fccf6464b76e25195108aed6b" }, { - "transactionIndex": 0, - "blockNumber": 19809239, - "transactionHash": "0x837343537cdf41fa333f23e5c53e028529174442f29a55f6e151ad1957ccd30c", + "transactionIndex": 1, + "blockNumber": 20388727, + "transactionHash": "0x203e6c24c67dd3d37a34ece54ef94825f32aecd0b82a197b8aecbcf0257e1c31", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -1244,13 +1244,13 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x000000000000000000000000000000000000000000000000003668c714da3200000000000000000000000000000000000000000000000003655c3ad2be71e129000000000000000000000000000000000000000000000000011d69614dc46e000000000000000000000000000000000000000000000000036525d20ba997af290000000000000000000000000000000000000000000000000153d228629ea000", - "logIndex": 1, - "blockHash": "0x8f4877311b1bf3829590fd66c0afd4bc24ed37db1d6a9223aa068b6db689e57d" + "data": "0x00000000000000000000000000000000000000000000000000414a887f6c3c000000000000000000000000000000000000000000000000033491435918b2a07400000000000000000000000000000000000000000000000003fb166ada6f2cf0000000000000000000000000000000000000000000000003344ff8d099466474000000000000000000000000000000000000000000000000043c60f359db68f0", + "logIndex": 3, + "blockHash": "0x4411e21aec3649d84112d39278c207d369d34c4fccf6464b76e25195108aed6b" } ], - "blockNumber": 19809239, - "cumulativeGasUsed": "5104951", + "blockNumber": 20388727, + "cumulativeGasUsed": "5125951", "status": 1, "byzantium": true }, @@ -1267,10 +1267,10 @@ "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1" ], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"invalidMarketId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"}],\"name\":\"GroupCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"groupId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"name\":\"GroupFinalizing\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"groupId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"marketName\",\"type\":\"string\"}],\"name\":\"GroupMarketAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"name\":\"GroupResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"_marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"_odds\",\"type\":\"uint256[][]\"}],\"name\":\"addOutcomesToGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_winningMarketIndex\",\"type\":\"uint256\"}],\"name\":\"beginResolvingGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"name\":\"finalizeGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"name\":\"getGroup\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Grouped.MarketGroup\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGroupByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Grouped.MarketGroup\",\"name\":\"_group\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"groupCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_groupName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_category\",\"type\":\"string\"}],\"name\":\"initializeGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfMarketGroups\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketGroups\",\"outputs\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"resolveMarketAsNo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_marketIndexes\",\"type\":\"uint256[]\"}],\"name\":\"resolveMarkets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/GroupedMarketFactoryV3.sol\":\"GroupedMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/GroupFetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Fetcher.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\n\\nabstract contract GroupFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticGroupBundle {\\n uint256 id;\\n string name;\\n StaticMarketBundle[] markets;\\n string[] marketNames;\\n StaticMarketBundle invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n // Dynamics\\n Grouped.GroupStatus status;\\n }\\n\\n struct DynamicGroupBundle {\\n uint256 id;\\n Grouped.GroupStatus status;\\n DynamicMarketBundle[] markets;\\n DynamicMarketBundle invalidMarket;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticGroupBundle[] memory _groupBundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_groupBundles, _lowestGroupIndex) = buildStaticGroupBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicGroupBundle[] memory _bundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestGroupIndex) = buildDynamicGroupBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new StaticGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticGroupBundle(_marketFactory, _ammFactory, _masterChef, _groupIds[i]);\\n }\\n }\\n\\n function buildDynamicGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new DynamicGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicGroupBundle(_marketFactory, _ammFactory, _groupIds[i]);\\n }\\n }\\n\\n function buildStaticGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _groupId\\n ) internal view returns (StaticGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.name = _group.name;\\n _bundle.status = _group.status;\\n _bundle.markets = _markets;\\n _bundle.endTime = _group.endTime;\\n _bundle.invalidMarket = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.invalidMarket\\n );\\n _bundle.invalidMarketName = _group.invalidMarketName;\\n _bundle.marketNames = _group.marketNames;\\n _bundle.category = _group.category;\\n }\\n\\n function buildDynamicGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _groupId\\n ) internal view returns (DynamicGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.markets = _markets;\\n _bundle.invalidMarket = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.invalidMarket\\n );\\n _bundle.status = _group.status;\\n }\\n\\n // Starts from the end of the groups list because newer groups are more interesting.\\n // _offset is skipping all groups, not just interesting groups\\n function listOfInterestingGroups(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingGroupIds, uint256 _groupIndex) {\\n _interestingGroupIds = new uint256[](_total);\\n\\n uint256 _groupCount = Grouped(_marketFactory).groupCount();\\n\\n // No groups so return nothing. (needed to avoid integer underflow below)\\n if (_groupCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _groupCount;\\n\\n // No remaining groups so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedGroups = 0;\\n _groupIndex = _max - _offset;\\n while (true) {\\n if (_collectedGroups >= _total) break;\\n if (_groupIndex == 0) break;\\n\\n _groupIndex--; // starts out one too high, so this works\\n\\n (Grouped.MarketGroup memory _group, uint256 _groupId) =\\n Grouped(_marketFactory).getGroupByIndex(_groupIndex);\\n\\n if (isGroupInteresting(_group, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingGroupIds[_collectedGroups] = _groupId;\\n _collectedGroups++;\\n }\\n }\\n\\n if (_total > _collectedGroups) {\\n assembly {\\n // shortens array\\n mstore(_interestingGroupIds, _collectedGroups)\\n }\\n }\\n }\\n\\n function isGroupInteresting(Grouped.MarketGroup memory _group, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _group.markets.length; i++) {\\n uint256 _marketId = _group.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n if (openOrHasWinningShares(_marketFactory, _group.invalidMarket)) {\\n return true;\\n }\\n\\n return false;\\n }\\n}\\n\\ncontract GroupedFetcher is GroupFetcher {\\n constructor() Fetcher(\\\"Grouped\\\", \\\"TBD\\\") {}\\n}\\n\",\"keccak256\":\"0xd8cb93eee1737373d56fd149e2bbbf81a3b1b0f6516bfc217acc402105474cfc\",\"license\":\"MIT\"},\"contracts/turbo/Grouped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./GroupFetcher.sol\\\";\\n\\nabstract contract Grouped is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds {\\n event GroupCreated(uint256 indexed id, uint256 endTime, uint256 invalidMarketId, string invalidMarketName);\\n event GroupMarketAdded(uint256 indexed groupId, uint256 marketId, string marketName);\\n event GroupFinalizing(uint256 indexed groupId, uint256 winningMarketIndex);\\n event GroupResolved(uint256 indexed id, bool valid);\\n\\n enum GroupStatus {Unknown, Scheduled, Finalizing, Final, Invalid}\\n\\n struct MarketGroup {\\n GroupStatus status;\\n string name;\\n uint256[] markets;\\n string[] marketNames;\\n uint256 invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n uint256 winningMarketIndex; // ignore when status is Scheduled. MAX_UINT is invalid\\n }\\n // GroupId => MarketGroup\\n mapping(uint256 => MarketGroup) public marketGroups;\\n uint256[] public listOfMarketGroups;\\n\\n // For regular markets, YES means the team won and NO means the team did not win.\\n // For the invalid market, YES means none of the teams won and NO means a team won.\\n uint256 constant OUTCOME_NO = 0;\\n uint256 constant OUTCOME_YES = 1;\\n\\n uint256 constant MAX_UINT = 2**256 - 1;\\n\\n function groupCount() public view returns (uint256) {\\n return listOfMarketGroups.length;\\n }\\n\\n function getGroup(uint256 _groupId) public view returns (MarketGroup memory) {\\n return marketGroups[_groupId];\\n }\\n\\n function getGroupByIndex(uint256 _index) public view returns (MarketGroup memory _group, uint256 _groupId) {\\n _groupId = listOfMarketGroups[_index];\\n _group = getGroup(_groupId);\\n }\\n\\n function startCreatingMarketGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n uint256 _endTime,\\n string memory _invalidMarketName,\\n string memory _category\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Unknown, \\\"group exists\\\");\\n\\n listOfMarketGroups.push(_groupId);\\n marketGroups[_groupId].status = GroupStatus.Scheduled;\\n marketGroups[_groupId].name = _groupName;\\n marketGroups[_groupId].endTime = _endTime;\\n marketGroups[_groupId].category = _category;\\n\\n uint256 _invalidMarket = startMarket(msg.sender, buildOutcomesNames(_invalidMarketName), invalidOdds(), true);\\n marketGroups[_groupId].invalidMarket = _invalidMarket;\\n marketGroups[_groupId].invalidMarketName = _invalidMarketName;\\n\\n emit GroupCreated(_groupId, _endTime, _invalidMarket, _invalidMarketName);\\n emit GroupMarketAdded(_groupId, _invalidMarket, _invalidMarketName);\\n }\\n\\n function addMarketToMarketGroup(\\n uint256 _groupId,\\n string memory _marketName,\\n uint256[] memory _odds\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Scheduled, \\\"group must be Scheduled\\\");\\n\\n uint256 _marketId = startMarket(msg.sender, buildOutcomesNames(_marketName), _odds, true);\\n marketGroups[_groupId].markets.push(_marketId);\\n marketGroups[_groupId].marketNames.push(_marketName);\\n emit GroupMarketAdded(_groupId, _marketId, _marketName);\\n }\\n\\n // Use MAX_UINT for _winningMarketIndex to indicate INVALID\\n function startResolvingMarketGroup(uint256 _groupId, uint256 _winningMarketIndex) internal {\\n bool _isInvalid = _winningMarketIndex == MAX_UINT;\\n MarketGroup memory _group = marketGroups[_groupId];\\n\\n require(_group.status == GroupStatus.Scheduled, \\\"group not Scheduled\\\");\\n\\n resolveInvalidMarket(_group, _isInvalid);\\n marketGroups[_groupId].status = GroupStatus.Finalizing;\\n marketGroups[_groupId].winningMarketIndex = _winningMarketIndex;\\n emit GroupFinalizing(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveFinalizingGroupMarket(uint256 _groupId, uint256 _marketIndex) internal {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing, \\\"must be finalizing\\\");\\n\\n uint256 _marketId = _group.markets[_marketIndex];\\n bool _wins = _marketIndex == _group.winningMarketIndex;\\n resolveGroupMarket(_marketId, _wins);\\n }\\n\\n function finalizeMarketGroup(uint256 _groupId) internal {\\n MarketGroup storage _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n bool _valid = _group.winningMarketIndex != MAX_UINT;\\n\\n _group.status = _valid ? GroupStatus.Final : GroupStatus.Invalid;\\n\\n emit GroupResolved(_groupId, _valid);\\n }\\n\\n function resolveGroupMarket(uint256 _marketId, bool _wins) internal {\\n uint256 _winningOutcome = _wins ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_marketId, _winningOutcome);\\n }\\n\\n function resolveInvalidMarket(MarketGroup memory _group, bool _invalid) private {\\n uint256 _outcomeIndex = _invalid ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_group.invalidMarket, _outcomeIndex);\\n }\\n\\n function buildOutcomesNames(string memory _marketName) internal pure returns (string[] memory _names) {\\n _names = new string[](2);\\n _names[OUTCOME_NO] = string(abi.encodePacked(\\\"NO - \\\", _marketName));\\n _names[OUTCOME_YES] = string(abi.encodePacked(\\\"YES - \\\", _marketName));\\n }\\n\\n function invalidOdds() private pure returns (uint256[] memory _odds) {\\n _odds = new uint256[](2);\\n _odds[OUTCOME_YES] = 1e18;\\n _odds[OUTCOME_NO] = 49e18;\\n }\\n}\\n\",\"keccak256\":\"0x6a6d5b95f52a895fd1bffcdbd0e5a5f4343c085bf7ae8309eb56951f5b50e2ef\",\"license\":\"MIT\"},\"contracts/turbo/GroupedMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract GroupedMarketFactoryV3 is AbstractMarketFactoryV3, Grouped, ManagedByLink, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {}\\n\\n function initializeGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n string memory _invalidMarketName,\\n uint256 _endTime,\\n string memory _category\\n ) public onlyLinkNode {\\n startCreatingMarketGroup(_groupId, _groupName, _endTime, _invalidMarketName, _category);\\n }\\n\\n function addOutcomesToGroup(\\n uint256 _groupId,\\n string[] memory _marketNames,\\n uint256[][] memory _odds\\n ) public onlyLinkNode {\\n require(_marketNames.length == _odds.length);\\n\\n for (uint256 i = 0; i < _marketNames.length; i++) {\\n addMarketToMarketGroup(_groupId, _marketNames[i], _odds[i]);\\n }\\n }\\n\\n // Set _winner to MAX_UINT (2*256 - 1) to indicate invalid\\n function beginResolvingGroup(uint256 _groupId, uint256 _winningMarketIndex) public onlyLinkNode {\\n startResolvingMarketGroup(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveMarkets(uint256 _groupId, uint256[] memory _marketIndexes) public onlyLinkNode {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n for (uint256 i = 0; i < _marketIndexes.length; i++) {\\n uint256 _marketIndex = _marketIndexes[i];\\n uint256 _marketId = _group.markets[_marketIndex];\\n if (isMarketResolved(_marketId)) continue; // skip resolved markets\\n resolveFinalizingGroupMarket(_groupId, _marketIndex);\\n }\\n }\\n\\n function finalizeGroup(uint256 _groupId) public onlyLinkNode {\\n finalizeMarketGroup(_groupId);\\n }\\n\\n // Used when some markets in a group can resolve early as NO.\\n // ex: Teams eliminated early from a tournament cannot win the overall tournament.\\n function resolveMarketAsNo(uint256 _marketId) public onlyLinkNode {\\n require(markets[_marketId].active, \\\"market inactive\\\");\\n resolveGroupMarket(_marketId, false);\\n }\\n\\n function getRewardEndTime(uint256 _eventId) public view override returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x2037f82962a9594e1ebe36e1d7239d967ecef033fa7cc1e9cd20e756f11c191a\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n HasSpreadMarket(Spread, InvalidName)\\n HasOverUnderMarket(OverUnder, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x0d4c083d82b07c94a03831f3b79e9cdc1f6016c3532199b03cbd7d81b7d2a757\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405260006007553480156200001657600080fd5b5060405162005ca838038062005ca88339810160408190526200003991620004ec565b604080518082019091526006815265076312e322e360d41b6020820152600080546001600160a01b03808b166001600160a01b03199283163317831617835560018054828c169084161790556009899055600280549189169190921617905582908990899089908990899089908290602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b390620001119086906000199060040162000608565b602060405180830381600087803b1580156200012c57600080fd5b505af115801562000141573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001679190620005df565b50600a62000174620002b5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001cb939285019291909101906200032b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200024d91600984019160209091019062000395565b506101409190910151600a909101805460ff19169115159190911790555050600d80546001600160a01b0319166001600160a01b03969096169590951790945550508251620002a69250600e91506020840190620003d3565b5050505050505050506200063a565b620002bf62000455565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b82805482825590600052602060002090810192821562000383579160200282015b828111156200038357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200034c565b5062000391929150620004c3565b5090565b82805482825590600052602060002090810192821562000383579160200282015b8281111562000383578251825591602001919060010190620003b6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200040b576000855562000383565b82601f106200042657805160ff191683800117855562000383565b8280016001018555821562000383579182018281111562000383578251825591602001919060010190620003b6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003915760008155600101620004c4565b8051620004e78162000621565b919050565b6000806000806000806000610120888a03121562000508578283fd5b8751620005158162000621565b809750506020808901516200052a8162000621565b60408a015160608b01519198509650620005448162000621565b9450609f89018a1362000555578384fd5b604051606081016001600160401b03811182821017156200057257fe5b6040528060808b0160e08c018d8111156200058b578788fd5b875b6003811015620005ac578251845292850192918501916001016200058d565b50839750620005bb81620004da565b96505050505050620005d16101008901620004da565b905092959891949750929550565b600060208284031215620005f1578081fd5b8151801515811462000601578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200063757600080fd5b50565b61565e806200064a6000396000f3fe60806040523480156200001157600080fd5b50600436106200028c5760003560e01c8063808e24181162000165578063cc87adea11620000d5578063dc9024da1162000093578063dc9024da1462000588578063e2c30b15146200059f578063e5678dfa14620005b6578063eb44fdd314620005cd578063ec97908214620005f3578063f2fde38b14620005fd576200028c565b8063cc87adea1462000520578063ceb606541462000537578063d4b6838e146200055d578063d5da4f1d1462000567578063d8dfeb45146200057e576200028c565b80638f23b32611620001235780638f23b32614620004d457806397eef18714620004de578063992c907914620004f5578063a544a62c146200050c578063b0e21e8a1462000516576200028c565b8063808e2418146200047b578063893d20e814620004925780638bdb957f146200049c5780638ce7442614620004b35780638e0ed19314620004bd576200028c565b806349a4d93411620002015780635653395111620001bf57806356533951146200040d5780637391b6d014620004395780637641ab011462000450578063787dce3d146200045a5780637d1d7fb81462000471576200028c565b806349a4d93414620003a35780634a7d036914620003ba5780634b2d9ffc14620003c45780634c9f66c714620003ce57806353ac55f514620003e7576200028c565b80633037faf1116200024f5780633037faf1146200031157806332ecabe9146200033857806335a9cdad146200034f57806342e0ed161462000375578063473a6d52146200038c576200028c565b80630a18a4aa14620002915780630d8e6e2c14620002aa57806319b5068714620002cc578063221fff8114620002e35780633025077b14620002fa575b600080fd5b620002a8620002a236600462003ca5565b62000614565b005b620002b46200063c565b604051620002c391906200400b565b60405180910390f35b620002a8620002dd36600462003a9b565b620006d6565b620002a8620002f436600462003cc7565b6200074b565b620002a86200030b36600462003c03565b62000a78565b620003286200032236600462003a9b565b62000aa6565b604051620002c392919062004181565b620002a86200034936600462003973565b62000adf565b620003666200036036600462003cc7565b62000b2d565b604051620002c3919062004276565b620003666200038636600462003a9b565b62000f66565b620003666200039d36600462003a9b565b62000f6e565b62000366620003b436600462003956565b62000faa565b6200036662000fbc565b6200036662001086565b620003d86200108c565b604051620002c3919062003f40565b620003fe620003f836600462003a9b565b6200109b565b604051620002c3919062003f91565b620004246200041e36600462003a9b565b62001225565b604051620002c3979695949392919062003f9c565b620002a86200044a36600462003af2565b62001413565b620003666200148b565b620002a86200046b36600462003a9b565b62001491565b62000366620014ae565b620003666200048c36600462003a9b565b620014b4565b620003d8620014d6565b620002a8620004ad36600462003a9b565b620014e5565b620003d862001508565b62000366620004ce36600462003956565b62001517565b62000366620015d3565b620002a8620004ef36600462003a9b565b620015d9565b620003666200050636600462003acd565b620015f6565b6200036662001a0f565b6200036662001a15565b620003666200053136600462003a9b565b62001a1b565b6200054e6200054836600462003a9b565b62001a22565b604051620002c391906200416c565b620003d862001d9c565b620002a86200057836600462003a9b565b62001dab565b620003d862001dc8565b620002a86200059936600462003bba565b62001dd7565b620002a8620005b036600462003956565b620021ea565b62000366620005c7366004620039ae565b62002256565b620005e4620005de36600462003a9b565b620022a4565b604051620002c39190620041a5565b6200036662002443565b620003fe6200060e36600462003956565b62002449565b600d546001600160a01b031633146200062c57600080fd5b620006388282620024b3565b5050565b600e8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006cc5780601f10620006a057610100808354040283529160200191620006cc565b820191906000526020600020905b815481529060010190602001808311620006ae57829003601f168201915b5050505050905090565b600d546001600160a01b03163314620006ee57600080fd5b600a8181548110620006fc57fe5b60009182526020909120600a600b90920201015460ff166200073b5760405162461bcd60e51b8152600401620007329062004118565b60405180910390fd5b62000748816000620028c5565b50565b600a5483106200075a57600080fd5b600a83815481106200076857fe5b60009182526020909120600a600b90920201015460ff166200078957600080fd5b6000620007968362000f6e565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007cd9033903090869060040162003f54565b602060405180830381600087803b158015620007e857600080fd5b505af1158015620007fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000823919062003a00565b506000600a85815481106200083457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620008b857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000899575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200097d57602002820191906000526020600020905b81548152602001906001019080831162000968575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000a335781602001518181518110620009bb57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b8152600401620009f292919062003f78565b600060405180830381600087803b15801562000a0d57600080fd5b505af115801562000a22573d6000803e3d6000fd5b5050600190920191506200099c9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f285858560405162000a699392919062004350565b60405180910390a15050505050565b600d546001600160a01b0316331462000a9057600080fd5b62000a9f8585848685620028eb565b5050505050565b62000ab062003612565b6000600c838154811062000ac057fe5b9060005260206000200154905062000ad88162001a22565b9150915091565b6000546001600160a01b0316331462000af757600080fd5b801562000b0a5762000b0862000fbc565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000b3f57600080fd5b600a848154811062000b4d57fe5b60009182526020909120600a600b90920201015460ff1662000b6e57600080fd5b6000600a858154811062000b7e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000c0257602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000be3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000cc757602002820191906000526020600020905b81548152602001906001019080831162000cb2575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000d7d578160200151818151811062000d0557fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000d3c92919062003f78565b600060405180830381600087803b15801562000d5757600080fd5b505af115801562000d6c573d6000803e3d6000fd5b50506001909201915062000ce69050565b50600062000d8b8562000f6e565b9050600062000dbc670de0b6b3a764000062000db58560a001518562002a9290919063ffffffff16565b9062002ac4565b9050600062000de6670de0b6b3a764000062000db58660c001518662002a9290919063ffffffff16565b905062000e008162000df9858562002ada565b9062002ada565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000e3d908990879060040162003f78565b602060405180830381600087803b15801562000e5857600080fd5b505af115801562000e6d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e93919062003a00565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000ec690849060040162004276565b602060405180830381600087803b15801562000ee157600080fd5b505af115801562000ef6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f1c919062003a00565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000f529392919062004350565b60405180910390a150909695505050505050565b60005b919050565b6000600954821015801562000f8d5750600954828162000f8a57fe5b06155b62000f9757600080fd5b600954828162000fa357fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000fd857503330145b62000fe257600080fd5b60075480156200108157600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926200102992911690859060040162003f78565b602060405180830381600087803b1580156200104457600080fd5b505af115801562001059573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200107f919062003a00565b505b905090565b60035481565b6002546001600160a01b031681565b600080600a8381548110620010ac57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200113057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001111575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011f557602002820191906000526020600020905b815481526020019060010190808311620011e0575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b600b602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f810186900486028301860190965285825260ff909216949293909290830182828015620012cd5780601f10620012a157610100808354040283529160200191620012cd565b820191906000526020600020905b815481529060010190602001808311620012af57829003601f168201915b50505050600483015460058401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620013685780601f106200133c5761010080835404028352916020019162001368565b820191906000526020600020905b8154815290600101906020018083116200134a57829003601f168201915b50505050600683015460078401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620014035780601f10620013d75761010080835404028352916020019162001403565b820191906000526020600020905b815481529060010190602001808311620013e557829003601f168201915b5050505050908060080154905087565b600d546001600160a01b031633146200142b57600080fd5b80518251146200143a57600080fd5b60005b825181101562001485576200147c848483815181106200145957fe5b60200260200101518484815181106200146e57fe5b602002602001015162002af0565b6001016200143d565b50505050565b60095481565b6000546001600160a01b03163314620014a957600080fd5b600555565b60045481565b600c8181548110620014c557600080fd5b600091825260209091200154905081565b6000546001600160a01b031690565b600d546001600160a01b03163314620014fd57600080fd5b620007488162002bd0565b6006546001600160a01b031681565b336000908152600860205260408120548015620015cd573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001575908690859060040162003f78565b602060405180830381600087803b1580156200159057600080fd5b505af1158015620015a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015cb919062003a00565b505b92915050565b600c5490565b6000546001600160a01b03163314620015f157600080fd5b600355565b600062001603836200109b565b620016225760405162461bcd60e51b8152600401620007329062004141565b6000600a84815481106200163257fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620016b657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001697575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200177b57602002820191906000526020600020905b81548152602001906001019080831162001766575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b0390911690637129778490620017cf90339060040162003f40565b602060405180830381600087803b158015620017ea57600080fd5b505af1158015620017ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001825919062003ab4565b905060095460095482816200183657fe5b040290506000620018478262000f6e565b9050600062001871670de0b6b3a764000062000db586608001518562002a9290919063ffffffff16565b90506200187f828262002ada565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb90620018ce908990869060040162003f78565b602060405180830381600087803b158015620018e957600080fd5b505af1158015620018fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001924919062003a00565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200196e57600080fd5b505afa15801562001983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620019ad919081019062003a1f565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b604051620019fa9796959493929190620042b8565b60405180910390a25091979650505050505050565b60075481565b60055481565b6009540290565b62001a2c62003612565b6000828152600b602052604090819020815161012081019092528054829060ff16600481111562001a5957fe5b600481111562001a6557fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001b065780601f1062001ada5761010080835404028352916020019162001b06565b820191906000526020600020905b81548152906001019060200180831162001ae857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001b6057602002820191906000526020600020905b81548152602001906001019080831162001b4b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562001c3f5760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001c2a5780601f1062001bfe5761010080835404028352916020019162001c2a565b820191906000526020600020905b81548152906001019060200180831162001c0c57829003601f168201915b50505050508152602001906001019062001b8e565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001ce05780601f1062001cb45761010080835404028352916020019162001ce0565b820191906000526020600020905b81548152906001019060200180831162001cc257829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001d825780601f1062001d565761010080835404028352916020019162001d82565b820191906000526020600020905b81548152906001019060200180831162001d6457829003601f168201915b505050505081526020016008820154815250509050919050565b600d546001600160a01b031681565b6000546001600160a01b0316331462001dc357600080fd5b600455565b6001546001600160a01b031681565b600d546001600160a01b0316331462001def57600080fd5b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562001e1b57fe5b600481111562001e2757fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001ec85780601f1062001e9c5761010080835404028352916020019162001ec8565b820191906000526020600020905b81548152906001019060200180831162001eaa57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001f2257602002820191906000526020600020905b81548152602001906001019080831162001f0d575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620020015760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001fec5780601f1062001fc05761010080835404028352916020019162001fec565b820191906000526020600020905b81548152906001019060200180831162001fce57829003601f168201915b50505050508152602001906001019062001f50565b50505090825250600482015460208083019190915260058301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620020a25780601f106200207657610100808354040283529160200191620020a2565b820191906000526020600020905b8154815290600101906020018083116200208457829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620021445780601f10620021185761010080835404028352916020019162002144565b820191906000526020600020905b8154815290600101906020018083116200212657829003601f168201915b50505091835250506008919091015460209091015290506002815160048111156200216b57fe5b146200217657600080fd5b60005b8251811015620014855760008382815181106200219257fe5b60200260200101519050600083604001518281518110620021af57fe5b60200260200101519050620021c4816200109b565b15620021d2575050620021e1565b620021de868362002c72565b50505b60010162002179565b6000546001600160a01b031633146200220257600080fd5b600d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b84518110156200229c5762002291620022898683815181106200227a57fe5b602002602001015186620015f6565b839062003043565b91506001016200225b565b509392505050565b620022ae6200365f565b600a548210620022ca57620022c262003056565b905062000f69565b600a8281548110620022d857fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200233d575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200242157602002820191906000526020600020905b8154815260200190600101908083116200240c575b5050509183525050600a919091015460ff161515602090910152905062000f69565b600a5490565b600080546001600160a01b031633146200246257600080fd5b6001600160a01b0382166200247657600080fd5b6000546200248e906001600160a01b03168362000638565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6000828152600b6020526040808220815161012081019092528054600019851493929190829060ff166004811115620024e857fe5b6004811115620024f457fe5b8152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620025955780601f10620025695761010080835404028352916020019162002595565b820191906000526020600020905b8154815290600101906020018083116200257757829003601f168201915b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620025ef57602002820191906000526020600020905b815481526020019060010190808311620025da575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620026ce5760008481526020908190208301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015620026b95780601f106200268d57610100808354040283529160200191620026b9565b820191906000526020600020905b8154815290600101906020018083116200269b57829003601f168201915b5050505050815260200190600101906200261d565b50505090825250600482015460208083019190915260058301805460408051601f600260001961010060018716150201909416939093049283018590048502810185018252828152940193928301828280156200276f5780601f1062002743576101008083540402835291602001916200276f565b820191906000526020600020905b8154815290600101906020018083116200275157829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620028115780601f10620027e55761010080835404028352916020019162002811565b820191906000526020600020905b815481529060010190602001808311620027f357829003601f168201915b50505091835250506008919091015460209091015290506001815160048111156200283857fe5b14620028585760405162461bcd60e51b8152600401620007329062004062565b620028648183620030cc565b6000848152600b602052604090819020805460ff191660021781556008018490555184907f6b437d58f4403cecb2353bf3e8f2384a91e7518f0a2b0e6762b0425b5e6c462190620028b790869062004276565b60405180910390a250505050565b600081620028d5576000620028d8565b60015b9050620028e68382620030ec565b505050565b6000858152600b602052604081205460ff1660048111156200290957fe5b14620029295760405162461bcd60e51b815260040162000732906200408f565b600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018690556000868152600b60209081526040909120805460ff19168317815586516200298a939190910191870190620036cd565b506000858152600b60209081526040909120600681018590558251620029b992600790920191840190620036cd565b506000620029de33620029cc8562003215565b620029d6620032be565b600162003328565b6000878152600b6020908152604090912060048101839055855192935062002a0f92600590910191860190620036cd565b50857fb4838dfe8d568d0b67fdac2db628f206c6ee584b385d7567e743755db005d00285838660405162002a46939291906200436f565b60405180910390a2857f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a6319828560405162002a8292919062004335565b60405180910390a2505050505050565b60008262002aa357506000620015cd565b8282028284828162002ab157fe5b041462002abd57600080fd5b9392505050565b60008082848162002ad157fe5b04949350505050565b60008282111562002aea57600080fd5b50900390565b60016000848152600b602052604090205460ff16600481111562002b1057fe5b1462002b305760405162461bcd60e51b81526004016200073290620040e1565b600062002b4b3362002b428562003215565b84600162003328565b6000858152600b6020908152604082206002810180546001818101835591855283852001859055600390910180549182018155835291819020865193945062002b9b9392019190860190620036cd565b50837f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a63198285604051620028b792919062004335565b6000818152600b602052604090206002815460ff16600481111562002bf157fe5b1462002bfc57600080fd5b600881015460001914158062002c1457600462002c17565b60035b8254839060ff1916600183600481111562002c2e57fe5b0217905550827f8b6ba55ee795a338c4c907ef43b3a72613c96c34ae6fce3131933cbf59ed4b638260405162002c65919062003f91565b60405180910390a2505050565b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562002c9e57fe5b600481111562002caa57fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562002d4b5780601f1062002d1f5761010080835404028352916020019162002d4b565b820191906000526020600020905b81548152906001019060200180831162002d2d57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562002da557602002820191906000526020600020905b81548152602001906001019080831162002d90575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562002e845760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562002e6f5780601f1062002e435761010080835404028352916020019162002e6f565b820191906000526020600020905b81548152906001019060200180831162002e5157829003601f168201915b50505050508152602001906001019062002dd3565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002f255780601f1062002ef95761010080835404028352916020019162002f25565b820191906000526020600020905b81548152906001019060200180831162002f0757829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002fc75780601f1062002f9b5761010080835404028352916020019162002fc7565b820191906000526020600020905b81548152906001019060200180831162002fa957829003601f168201915b505050918352505060089190910154602090910152905060028151600481111562002fee57fe5b146200300e5760405162461bcd60e51b81526004016200073290620040b5565b6000816040015183815181106200302157fe5b6020026020010151905060008261010001518414905062000a9f8282620028c5565b60008282018381101562002abd57600080fd5b620030606200365f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600081620030dc576000620030df565b60015b9050620028e68360800151825b6000600a8381548110620030fc57fe5b90600052602060002090600b0201905060008160010183815481106200311e57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b1580156200319d57600080fd5b505afa158015620031b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031dc919081019062003a1f565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f8583868460405162000a6994939291906200427f565b6040805160028082526060828101909352816020015b60608152602001906001900390816200322b5790505090508160405160200162003256919062003f11565b604051602081830303815290604052816000815181106200327357fe5b60200260200101819052508160405160200162003291919062003ee1565b60405160208183030381529060405281600181518110620032ae57fe5b6020026020010181905250919050565b6040805160028082526060808301845292602083019080368337019050509050670de0b6b3a764000081600181518110620032f557fe5b6020026020010181815250506802a802f8630a240000816000815181106200331957fe5b60200260200101818152505090565b600a80546040805161016081019091526001600160a01b0387168152909190602081016200335787306200351d565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033f79392850192919091019062003762565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003479916009840191602090910190620037ba565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620034cc9083908790879062004306565b60405180910390a1811562003515577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200350c919062004276565b60405180910390a15b949350505050565b815160609060008167ffffffffffffffff811180156200353c57600080fd5b5060405190808252806020026020018201604052801562003567578160200160208202803683370190505b50905060005b8281101562003609578581815181106200358357fe5b60200260200101518682815181106200359857fe5b602002602001015186604051620035af90620037f7565b620035bd9392919062004020565b604051809103906000f080158015620035da573d6000803e3d6000fd5b50828281518110620035e857fe5b6001600160a01b03909216602092830291909101909101526001016200356d565b50949350505050565b604080516101208101909152806000815260200160608152602001606081526020016060815260200160008152602001606081526020016000815260200160608152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262003705576000855562003750565b82601f106200372057805160ff191683800117855562003750565b8280016001018555821562003750579182015b828111156200375057825182559160200191906001019062003733565b506200375e92915062003805565b5090565b82805482825590600052602060002090810192821562003750579160200282015b828111156200375057825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003783565b8280548282559060005260206000209081019282156200375057916020028201828111156200375057825182559160200191906001019062003733565b6111f3806200443683390190565b5b808211156200375e576000815560010162003806565b80356001600160a01b038116811462000f6957600080fd5b600082601f83011262003845578081fd5b813560206200385e6200385883620043b5565b62004390565b82815281810190858301855b85811015620038975762003884898684358b0101620038a4565b845292840192908401906001016200386a565b5090979650505050505050565b600082601f830112620038b5578081fd5b81356020620038c86200385883620043b5565b8281528181019085830183850287018401881015620038e5578586fd5b855b858110156200389757813584529284019290840190600101620038e7565b600082601f83011262003916578081fd5b8135620039276200385882620043d4565b8181528460208386010111156200393c578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003968578081fd5b62002abd826200381c565b6000806040838503121562003986578081fd5b62003991836200381c565b91506020830135620039a38162004426565b809150509250929050565b60008060408385031215620039c1578182fd5b823567ffffffffffffffff811115620039d8578283fd5b620039e685828601620038a4565b925050620039f7602084016200381c565b90509250929050565b60006020828403121562003a12578081fd5b815162002abd8162004426565b60006020828403121562003a31578081fd5b815167ffffffffffffffff81111562003a48578182fd5b8201601f8101841362003a59578182fd5b805162003a6a6200385882620043d4565b81815285602083850101111562003a7f578384fd5b62003a92826020830160208601620043f7565b95945050505050565b60006020828403121562003aad578081fd5b5035919050565b60006020828403121562003ac6578081fd5b5051919050565b6000806040838503121562003ae0578182fd5b82359150620039f7602084016200381c565b60008060006060848603121562003b07578081fd5b8335925060208085013567ffffffffffffffff8082111562003b27578384fd5b818701915087601f83011262003b3b578384fd5b813562003b4c6200385882620043b5565b81815284810190848601875b8481101562003b855762003b728d8984358a010162003905565b8452928701929087019060010162003b58565b50909750505050604087013592508083111562003ba0578384fd5b505062003bb08682870162003834565b9150509250925092565b6000806040838503121562003bcd578182fd5b82359150602083013567ffffffffffffffff81111562003beb578182fd5b62003bf985828601620038a4565b9150509250929050565b600080600080600060a0868803121562003c1b578283fd5b85359450602086013567ffffffffffffffff8082111562003c3a578485fd5b62003c4889838a0162003905565b9550604088013591508082111562003c5e578485fd5b62003c6c89838a0162003905565b945060608801359350608088013591508082111562003c89578283fd5b5062003c988882890162003905565b9150509295509295909350565b6000806040838503121562003cb8578182fd5b50508035926020909101359150565b60008060006060848603121562003cdc578081fd5b833592506020840135915062003cf5604085016200381c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d455781516001600160a01b03168752958201959082019060010162003d1e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101562003d9a57828403895262003d8784835162003ded565b9885019893509084019060010162003d6c565b5091979650505050505050565b6000815180845260208085019450808401835b8381101562003d455781518752958201959082019060010162003dba565b15159052565b6005811062003de957fe5b9052565b6000815180845262003e07816020860160208601620043f7565b601f01601f19169290920160200192915050565b600061012062003e2d84845162003dde565b602083015181602086015262003e468286018262003ded565b9150506040830151848203604086015262003e62828262003da7565b9150506060830151848203606086015262003e7e828262003d50565b9150506080830151608085015260a083015184820360a086015262003ea4828262003ded565b91505060c083015160c085015260e083015184820360e086015262003eca828262003ded565b610100948501519590940194909452509092915050565b60006502ca2a99016960d51b8252825162003f04816006850160208701620043f7565b9190910160060192915050565b600064027279016960dd1b8252825162003f33816005850160208701620043f7565b9190910160050192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600062003faa828a62003dde565b60e0602083015262003fc060e083018962003ded565b876040840152828103606084015262003fda818862003ded565b905085608084015282810360a084015262003ff6818662003ded565b9150508260c083015298975050505050505050565b60006020825262002abd602083018462003ded565b60006060825262004035606083018662003ded565b828103602084015262004049818662003ded565b91505060018060a01b0383166040830152949350505050565b60208082526013908201527219dc9bdd5c081b9bdd0814d8da19591d5b1959606a1b604082015260600190565b6020808252600c908201526b67726f75702065786973747360a01b604082015260600190565b6020808252601290820152716d7573742062652066696e616c697a696e6760701b604082015260600190565b60208082526017908201527f67726f7570206d757374206265205363686564756c6564000000000000000000604082015260600190565b6020808252600f908201526e6d61726b657420696e61637469766560881b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262002abd602083018462003e1b565b60006040825262004196604083018562003e1b565b90508260208301529392505050565b600060208252620041bb60208301845162003cfe565b6020830151610160806040850152620041d961018085018362003d0b565b91506040850151620041ef606086018262003cfe565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262004255848362003da7565b9350808701519150506200426c8286018262003dd8565b5090949350505050565b90815260200190565b600085825260018060a01b038516602083015283604083015260806060830152620042ae608083018462003ded565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e06060830152620042e760e083018762003ded565b60808301959095525060a081019290925260c090910152949350505050565b60008482526060602083015262004321606083018562003d50565b8281036040840152620042ae818562003da7565b60008382526040602083015262003515604083018462003ded565b92835260208301919091526001600160a01b0316604082015260600190565b60008482528360208301526060604083015262003a92606083018462003ded565b60405181810167ffffffffffffffff81118282101715620043ad57fe5b604052919050565b600067ffffffffffffffff821115620043ca57fe5b5060209081020190565b600067ffffffffffffffff821115620043e957fe5b50601f01601f191660200190565b60005b8381101562004414578181015183820152602001620043fa565b83811115620014855750506000910152565b80151581146200074857600080fdfe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212206291d1a775b644667362d424118b7bf4accddf62ff27dd7ad347f9fed58fd37964736f6c63430007060033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200028c5760003560e01c8063808e24181162000165578063cc87adea11620000d5578063dc9024da1162000093578063dc9024da1462000588578063e2c30b15146200059f578063e5678dfa14620005b6578063eb44fdd314620005cd578063ec97908214620005f3578063f2fde38b14620005fd576200028c565b8063cc87adea1462000520578063ceb606541462000537578063d4b6838e146200055d578063d5da4f1d1462000567578063d8dfeb45146200057e576200028c565b80638f23b32611620001235780638f23b32614620004d457806397eef18714620004de578063992c907914620004f5578063a544a62c146200050c578063b0e21e8a1462000516576200028c565b8063808e2418146200047b578063893d20e814620004925780638bdb957f146200049c5780638ce7442614620004b35780638e0ed19314620004bd576200028c565b806349a4d93411620002015780635653395111620001bf57806356533951146200040d5780637391b6d014620004395780637641ab011462000450578063787dce3d146200045a5780637d1d7fb81462000471576200028c565b806349a4d93414620003a35780634a7d036914620003ba5780634b2d9ffc14620003c45780634c9f66c714620003ce57806353ac55f514620003e7576200028c565b80633037faf1116200024f5780633037faf1146200031157806332ecabe9146200033857806335a9cdad146200034f57806342e0ed161462000375578063473a6d52146200038c576200028c565b80630a18a4aa14620002915780630d8e6e2c14620002aa57806319b5068714620002cc578063221fff8114620002e35780633025077b14620002fa575b600080fd5b620002a8620002a236600462003ca5565b62000614565b005b620002b46200063c565b604051620002c391906200400b565b60405180910390f35b620002a8620002dd36600462003a9b565b620006d6565b620002a8620002f436600462003cc7565b6200074b565b620002a86200030b36600462003c03565b62000a78565b620003286200032236600462003a9b565b62000aa6565b604051620002c392919062004181565b620002a86200034936600462003973565b62000adf565b620003666200036036600462003cc7565b62000b2d565b604051620002c3919062004276565b620003666200038636600462003a9b565b62000f66565b620003666200039d36600462003a9b565b62000f6e565b62000366620003b436600462003956565b62000faa565b6200036662000fbc565b6200036662001086565b620003d86200108c565b604051620002c3919062003f40565b620003fe620003f836600462003a9b565b6200109b565b604051620002c3919062003f91565b620004246200041e36600462003a9b565b62001225565b604051620002c3979695949392919062003f9c565b620002a86200044a36600462003af2565b62001413565b620003666200148b565b620002a86200046b36600462003a9b565b62001491565b62000366620014ae565b620003666200048c36600462003a9b565b620014b4565b620003d8620014d6565b620002a8620004ad36600462003a9b565b620014e5565b620003d862001508565b62000366620004ce36600462003956565b62001517565b62000366620015d3565b620002a8620004ef36600462003a9b565b620015d9565b620003666200050636600462003acd565b620015f6565b6200036662001a0f565b6200036662001a15565b620003666200053136600462003a9b565b62001a1b565b6200054e6200054836600462003a9b565b62001a22565b604051620002c391906200416c565b620003d862001d9c565b620002a86200057836600462003a9b565b62001dab565b620003d862001dc8565b620002a86200059936600462003bba565b62001dd7565b620002a8620005b036600462003956565b620021ea565b62000366620005c7366004620039ae565b62002256565b620005e4620005de36600462003a9b565b620022a4565b604051620002c39190620041a5565b6200036662002443565b620003fe6200060e36600462003956565b62002449565b600d546001600160a01b031633146200062c57600080fd5b620006388282620024b3565b5050565b600e8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006cc5780601f10620006a057610100808354040283529160200191620006cc565b820191906000526020600020905b815481529060010190602001808311620006ae57829003601f168201915b5050505050905090565b600d546001600160a01b03163314620006ee57600080fd5b600a8181548110620006fc57fe5b60009182526020909120600a600b90920201015460ff166200073b5760405162461bcd60e51b8152600401620007329062004118565b60405180910390fd5b62000748816000620028c5565b50565b600a5483106200075a57600080fd5b600a83815481106200076857fe5b60009182526020909120600a600b90920201015460ff166200078957600080fd5b6000620007968362000f6e565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007cd9033903090869060040162003f54565b602060405180830381600087803b158015620007e857600080fd5b505af1158015620007fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000823919062003a00565b506000600a85815481106200083457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620008b857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000899575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200097d57602002820191906000526020600020905b81548152602001906001019080831162000968575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000a335781602001518181518110620009bb57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b8152600401620009f292919062003f78565b600060405180830381600087803b15801562000a0d57600080fd5b505af115801562000a22573d6000803e3d6000fd5b5050600190920191506200099c9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f285858560405162000a699392919062004350565b60405180910390a15050505050565b600d546001600160a01b0316331462000a9057600080fd5b62000a9f8585848685620028eb565b5050505050565b62000ab062003612565b6000600c838154811062000ac057fe5b9060005260206000200154905062000ad88162001a22565b9150915091565b6000546001600160a01b0316331462000af757600080fd5b801562000b0a5762000b0862000fbc565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000b3f57600080fd5b600a848154811062000b4d57fe5b60009182526020909120600a600b90920201015460ff1662000b6e57600080fd5b6000600a858154811062000b7e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000c0257602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000be3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000cc757602002820191906000526020600020905b81548152602001906001019080831162000cb2575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000d7d578160200151818151811062000d0557fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000d3c92919062003f78565b600060405180830381600087803b15801562000d5757600080fd5b505af115801562000d6c573d6000803e3d6000fd5b50506001909201915062000ce69050565b50600062000d8b8562000f6e565b9050600062000dbc670de0b6b3a764000062000db58560a001518562002a9290919063ffffffff16565b9062002ac4565b9050600062000de6670de0b6b3a764000062000db58660c001518662002a9290919063ffffffff16565b905062000e008162000df9858562002ada565b9062002ada565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000e3d908990879060040162003f78565b602060405180830381600087803b15801562000e5857600080fd5b505af115801562000e6d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e93919062003a00565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000ec690849060040162004276565b602060405180830381600087803b15801562000ee157600080fd5b505af115801562000ef6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f1c919062003a00565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000f529392919062004350565b60405180910390a150909695505050505050565b60005b919050565b6000600954821015801562000f8d5750600954828162000f8a57fe5b06155b62000f9757600080fd5b600954828162000fa357fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000fd857503330145b62000fe257600080fd5b60075480156200108157600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926200102992911690859060040162003f78565b602060405180830381600087803b1580156200104457600080fd5b505af115801562001059573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200107f919062003a00565b505b905090565b60035481565b6002546001600160a01b031681565b600080600a8381548110620010ac57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200113057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001111575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011f557602002820191906000526020600020905b815481526020019060010190808311620011e0575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b600b602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f810186900486028301860190965285825260ff909216949293909290830182828015620012cd5780601f10620012a157610100808354040283529160200191620012cd565b820191906000526020600020905b815481529060010190602001808311620012af57829003601f168201915b50505050600483015460058401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620013685780601f106200133c5761010080835404028352916020019162001368565b820191906000526020600020905b8154815290600101906020018083116200134a57829003601f168201915b50505050600683015460078401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620014035780601f10620013d75761010080835404028352916020019162001403565b820191906000526020600020905b815481529060010190602001808311620013e557829003601f168201915b5050505050908060080154905087565b600d546001600160a01b031633146200142b57600080fd5b80518251146200143a57600080fd5b60005b825181101562001485576200147c848483815181106200145957fe5b60200260200101518484815181106200146e57fe5b602002602001015162002af0565b6001016200143d565b50505050565b60095481565b6000546001600160a01b03163314620014a957600080fd5b600555565b60045481565b600c8181548110620014c557600080fd5b600091825260209091200154905081565b6000546001600160a01b031690565b600d546001600160a01b03163314620014fd57600080fd5b620007488162002bd0565b6006546001600160a01b031681565b336000908152600860205260408120548015620015cd573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001575908690859060040162003f78565b602060405180830381600087803b1580156200159057600080fd5b505af1158015620015a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015cb919062003a00565b505b92915050565b600c5490565b6000546001600160a01b03163314620015f157600080fd5b600355565b600062001603836200109b565b620016225760405162461bcd60e51b8152600401620007329062004141565b6000600a84815481106200163257fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620016b657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001697575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200177b57602002820191906000526020600020905b81548152602001906001019080831162001766575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b0390911690637129778490620017cf90339060040162003f40565b602060405180830381600087803b158015620017ea57600080fd5b505af1158015620017ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001825919062003ab4565b905060095460095482816200183657fe5b040290506000620018478262000f6e565b9050600062001871670de0b6b3a764000062000db586608001518562002a9290919063ffffffff16565b90506200187f828262002ada565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb90620018ce908990869060040162003f78565b602060405180830381600087803b158015620018e957600080fd5b505af1158015620018fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001924919062003a00565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200196e57600080fd5b505afa15801562001983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620019ad919081019062003a1f565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b604051620019fa9796959493929190620042b8565b60405180910390a25091979650505050505050565b60075481565b60055481565b6009540290565b62001a2c62003612565b6000828152600b602052604090819020815161012081019092528054829060ff16600481111562001a5957fe5b600481111562001a6557fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001b065780601f1062001ada5761010080835404028352916020019162001b06565b820191906000526020600020905b81548152906001019060200180831162001ae857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001b6057602002820191906000526020600020905b81548152602001906001019080831162001b4b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562001c3f5760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001c2a5780601f1062001bfe5761010080835404028352916020019162001c2a565b820191906000526020600020905b81548152906001019060200180831162001c0c57829003601f168201915b50505050508152602001906001019062001b8e565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001ce05780601f1062001cb45761010080835404028352916020019162001ce0565b820191906000526020600020905b81548152906001019060200180831162001cc257829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001d825780601f1062001d565761010080835404028352916020019162001d82565b820191906000526020600020905b81548152906001019060200180831162001d6457829003601f168201915b505050505081526020016008820154815250509050919050565b600d546001600160a01b031681565b6000546001600160a01b0316331462001dc357600080fd5b600455565b6001546001600160a01b031681565b600d546001600160a01b0316331462001def57600080fd5b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562001e1b57fe5b600481111562001e2757fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001ec85780601f1062001e9c5761010080835404028352916020019162001ec8565b820191906000526020600020905b81548152906001019060200180831162001eaa57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001f2257602002820191906000526020600020905b81548152602001906001019080831162001f0d575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620020015760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001fec5780601f1062001fc05761010080835404028352916020019162001fec565b820191906000526020600020905b81548152906001019060200180831162001fce57829003601f168201915b50505050508152602001906001019062001f50565b50505090825250600482015460208083019190915260058301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620020a25780601f106200207657610100808354040283529160200191620020a2565b820191906000526020600020905b8154815290600101906020018083116200208457829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620021445780601f10620021185761010080835404028352916020019162002144565b820191906000526020600020905b8154815290600101906020018083116200212657829003601f168201915b50505091835250506008919091015460209091015290506002815160048111156200216b57fe5b146200217657600080fd5b60005b8251811015620014855760008382815181106200219257fe5b60200260200101519050600083604001518281518110620021af57fe5b60200260200101519050620021c4816200109b565b15620021d2575050620021e1565b620021de868362002c72565b50505b60010162002179565b6000546001600160a01b031633146200220257600080fd5b600d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b84518110156200229c5762002291620022898683815181106200227a57fe5b602002602001015186620015f6565b839062003043565b91506001016200225b565b509392505050565b620022ae6200365f565b600a548210620022ca57620022c262003056565b905062000f69565b600a8281548110620022d857fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200233d575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200242157602002820191906000526020600020905b8154815260200190600101908083116200240c575b5050509183525050600a919091015460ff161515602090910152905062000f69565b600a5490565b600080546001600160a01b031633146200246257600080fd5b6001600160a01b0382166200247657600080fd5b6000546200248e906001600160a01b03168362000638565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6000828152600b6020526040808220815161012081019092528054600019851493929190829060ff166004811115620024e857fe5b6004811115620024f457fe5b8152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620025955780601f10620025695761010080835404028352916020019162002595565b820191906000526020600020905b8154815290600101906020018083116200257757829003601f168201915b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620025ef57602002820191906000526020600020905b815481526020019060010190808311620025da575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620026ce5760008481526020908190208301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015620026b95780601f106200268d57610100808354040283529160200191620026b9565b820191906000526020600020905b8154815290600101906020018083116200269b57829003601f168201915b5050505050815260200190600101906200261d565b50505090825250600482015460208083019190915260058301805460408051601f600260001961010060018716150201909416939093049283018590048502810185018252828152940193928301828280156200276f5780601f1062002743576101008083540402835291602001916200276f565b820191906000526020600020905b8154815290600101906020018083116200275157829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620028115780601f10620027e55761010080835404028352916020019162002811565b820191906000526020600020905b815481529060010190602001808311620027f357829003601f168201915b50505091835250506008919091015460209091015290506001815160048111156200283857fe5b14620028585760405162461bcd60e51b8152600401620007329062004062565b620028648183620030cc565b6000848152600b602052604090819020805460ff191660021781556008018490555184907f6b437d58f4403cecb2353bf3e8f2384a91e7518f0a2b0e6762b0425b5e6c462190620028b790869062004276565b60405180910390a250505050565b600081620028d5576000620028d8565b60015b9050620028e68382620030ec565b505050565b6000858152600b602052604081205460ff1660048111156200290957fe5b14620029295760405162461bcd60e51b815260040162000732906200408f565b600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018690556000868152600b60209081526040909120805460ff19168317815586516200298a939190910191870190620036cd565b506000858152600b60209081526040909120600681018590558251620029b992600790920191840190620036cd565b506000620029de33620029cc8562003215565b620029d6620032be565b600162003328565b6000878152600b6020908152604090912060048101839055855192935062002a0f92600590910191860190620036cd565b50857fb4838dfe8d568d0b67fdac2db628f206c6ee584b385d7567e743755db005d00285838660405162002a46939291906200436f565b60405180910390a2857f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a6319828560405162002a8292919062004335565b60405180910390a2505050505050565b60008262002aa357506000620015cd565b8282028284828162002ab157fe5b041462002abd57600080fd5b9392505050565b60008082848162002ad157fe5b04949350505050565b60008282111562002aea57600080fd5b50900390565b60016000848152600b602052604090205460ff16600481111562002b1057fe5b1462002b305760405162461bcd60e51b81526004016200073290620040e1565b600062002b4b3362002b428562003215565b84600162003328565b6000858152600b6020908152604082206002810180546001818101835591855283852001859055600390910180549182018155835291819020865193945062002b9b9392019190860190620036cd565b50837f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a63198285604051620028b792919062004335565b6000818152600b602052604090206002815460ff16600481111562002bf157fe5b1462002bfc57600080fd5b600881015460001914158062002c1457600462002c17565b60035b8254839060ff1916600183600481111562002c2e57fe5b0217905550827f8b6ba55ee795a338c4c907ef43b3a72613c96c34ae6fce3131933cbf59ed4b638260405162002c65919062003f91565b60405180910390a2505050565b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562002c9e57fe5b600481111562002caa57fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562002d4b5780601f1062002d1f5761010080835404028352916020019162002d4b565b820191906000526020600020905b81548152906001019060200180831162002d2d57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562002da557602002820191906000526020600020905b81548152602001906001019080831162002d90575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562002e845760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562002e6f5780601f1062002e435761010080835404028352916020019162002e6f565b820191906000526020600020905b81548152906001019060200180831162002e5157829003601f168201915b50505050508152602001906001019062002dd3565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002f255780601f1062002ef95761010080835404028352916020019162002f25565b820191906000526020600020905b81548152906001019060200180831162002f0757829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002fc75780601f1062002f9b5761010080835404028352916020019162002fc7565b820191906000526020600020905b81548152906001019060200180831162002fa957829003601f168201915b505050918352505060089190910154602090910152905060028151600481111562002fee57fe5b146200300e5760405162461bcd60e51b81526004016200073290620040b5565b6000816040015183815181106200302157fe5b6020026020010151905060008261010001518414905062000a9f8282620028c5565b60008282018381101562002abd57600080fd5b620030606200365f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600081620030dc576000620030df565b60015b9050620028e68360800151825b6000600a8381548110620030fc57fe5b90600052602060002090600b0201905060008160010183815481106200311e57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b1580156200319d57600080fd5b505afa158015620031b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031dc919081019062003a1f565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f8583868460405162000a6994939291906200427f565b6040805160028082526060828101909352816020015b60608152602001906001900390816200322b5790505090508160405160200162003256919062003f11565b604051602081830303815290604052816000815181106200327357fe5b60200260200101819052508160405160200162003291919062003ee1565b60405160208183030381529060405281600181518110620032ae57fe5b6020026020010181905250919050565b6040805160028082526060808301845292602083019080368337019050509050670de0b6b3a764000081600181518110620032f557fe5b6020026020010181815250506802a802f8630a240000816000815181106200331957fe5b60200260200101818152505090565b600a80546040805161016081019091526001600160a01b0387168152909190602081016200335787306200351d565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033f79392850192919091019062003762565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003479916009840191602090910190620037ba565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620034cc9083908790879062004306565b60405180910390a1811562003515577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200350c919062004276565b60405180910390a15b949350505050565b815160609060008167ffffffffffffffff811180156200353c57600080fd5b5060405190808252806020026020018201604052801562003567578160200160208202803683370190505b50905060005b8281101562003609578581815181106200358357fe5b60200260200101518682815181106200359857fe5b602002602001015186604051620035af90620037f7565b620035bd9392919062004020565b604051809103906000f080158015620035da573d6000803e3d6000fd5b50828281518110620035e857fe5b6001600160a01b03909216602092830291909101909101526001016200356d565b50949350505050565b604080516101208101909152806000815260200160608152602001606081526020016060815260200160008152602001606081526020016000815260200160608152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262003705576000855562003750565b82601f106200372057805160ff191683800117855562003750565b8280016001018555821562003750579182015b828111156200375057825182559160200191906001019062003733565b506200375e92915062003805565b5090565b82805482825590600052602060002090810192821562003750579160200282015b828111156200375057825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003783565b8280548282559060005260206000209081019282156200375057916020028201828111156200375057825182559160200191906001019062003733565b6111f3806200443683390190565b5b808211156200375e576000815560010162003806565b80356001600160a01b038116811462000f6957600080fd5b600082601f83011262003845578081fd5b813560206200385e6200385883620043b5565b62004390565b82815281810190858301855b85811015620038975762003884898684358b0101620038a4565b845292840192908401906001016200386a565b5090979650505050505050565b600082601f830112620038b5578081fd5b81356020620038c86200385883620043b5565b8281528181019085830183850287018401881015620038e5578586fd5b855b858110156200389757813584529284019290840190600101620038e7565b600082601f83011262003916578081fd5b8135620039276200385882620043d4565b8181528460208386010111156200393c578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003968578081fd5b62002abd826200381c565b6000806040838503121562003986578081fd5b62003991836200381c565b91506020830135620039a38162004426565b809150509250929050565b60008060408385031215620039c1578182fd5b823567ffffffffffffffff811115620039d8578283fd5b620039e685828601620038a4565b925050620039f7602084016200381c565b90509250929050565b60006020828403121562003a12578081fd5b815162002abd8162004426565b60006020828403121562003a31578081fd5b815167ffffffffffffffff81111562003a48578182fd5b8201601f8101841362003a59578182fd5b805162003a6a6200385882620043d4565b81815285602083850101111562003a7f578384fd5b62003a92826020830160208601620043f7565b95945050505050565b60006020828403121562003aad578081fd5b5035919050565b60006020828403121562003ac6578081fd5b5051919050565b6000806040838503121562003ae0578182fd5b82359150620039f7602084016200381c565b60008060006060848603121562003b07578081fd5b8335925060208085013567ffffffffffffffff8082111562003b27578384fd5b818701915087601f83011262003b3b578384fd5b813562003b4c6200385882620043b5565b81815284810190848601875b8481101562003b855762003b728d8984358a010162003905565b8452928701929087019060010162003b58565b50909750505050604087013592508083111562003ba0578384fd5b505062003bb08682870162003834565b9150509250925092565b6000806040838503121562003bcd578182fd5b82359150602083013567ffffffffffffffff81111562003beb578182fd5b62003bf985828601620038a4565b9150509250929050565b600080600080600060a0868803121562003c1b578283fd5b85359450602086013567ffffffffffffffff8082111562003c3a578485fd5b62003c4889838a0162003905565b9550604088013591508082111562003c5e578485fd5b62003c6c89838a0162003905565b945060608801359350608088013591508082111562003c89578283fd5b5062003c988882890162003905565b9150509295509295909350565b6000806040838503121562003cb8578182fd5b50508035926020909101359150565b60008060006060848603121562003cdc578081fd5b833592506020840135915062003cf5604085016200381c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d455781516001600160a01b03168752958201959082019060010162003d1e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101562003d9a57828403895262003d8784835162003ded565b9885019893509084019060010162003d6c565b5091979650505050505050565b6000815180845260208085019450808401835b8381101562003d455781518752958201959082019060010162003dba565b15159052565b6005811062003de957fe5b9052565b6000815180845262003e07816020860160208601620043f7565b601f01601f19169290920160200192915050565b600061012062003e2d84845162003dde565b602083015181602086015262003e468286018262003ded565b9150506040830151848203604086015262003e62828262003da7565b9150506060830151848203606086015262003e7e828262003d50565b9150506080830151608085015260a083015184820360a086015262003ea4828262003ded565b91505060c083015160c085015260e083015184820360e086015262003eca828262003ded565b610100948501519590940194909452509092915050565b60006502ca2a99016960d51b8252825162003f04816006850160208701620043f7565b9190910160060192915050565b600064027279016960dd1b8252825162003f33816005850160208701620043f7565b9190910160050192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600062003faa828a62003dde565b60e0602083015262003fc060e083018962003ded565b876040840152828103606084015262003fda818862003ded565b905085608084015282810360a084015262003ff6818662003ded565b9150508260c083015298975050505050505050565b60006020825262002abd602083018462003ded565b60006060825262004035606083018662003ded565b828103602084015262004049818662003ded565b91505060018060a01b0383166040830152949350505050565b60208082526013908201527219dc9bdd5c081b9bdd0814d8da19591d5b1959606a1b604082015260600190565b6020808252600c908201526b67726f75702065786973747360a01b604082015260600190565b6020808252601290820152716d7573742062652066696e616c697a696e6760701b604082015260600190565b60208082526017908201527f67726f7570206d757374206265205363686564756c6564000000000000000000604082015260600190565b6020808252600f908201526e6d61726b657420696e61637469766560881b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262002abd602083018462003e1b565b60006040825262004196604083018562003e1b565b90508260208301529392505050565b600060208252620041bb60208301845162003cfe565b6020830151610160806040850152620041d961018085018362003d0b565b91506040850151620041ef606086018262003cfe565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262004255848362003da7565b9350808701519150506200426c8286018262003dd8565b5090949350505050565b90815260200190565b600085825260018060a01b038516602083015283604083015260806060830152620042ae608083018462003ded565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e06060830152620042e760e083018762003ded565b60808301959095525060a081019290925260c090910152949350505050565b60008482526060602083015262004321606083018562003d50565b8281036040840152620042ae818562003da7565b60008382526040602083015262003515604083018462003ded565b92835260208301919091526001600160a01b0316604082015260600190565b60008482528360208301526060604083015262003a92606083018462003ded565b60405181810167ffffffffffffffff81118282101715620043ad57fe5b604052919050565b600067ffffffffffffffff821115620043ca57fe5b5060209081020190565b600067ffffffffffffffff821115620043e957fe5b50601f01601f191660200190565b60005b8381101562004414578181015183820152602001620043fa565b83811115620014855750506000910152565b80151581146200074857600080fdfe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212206291d1a775b644667362d424118b7bf4accddf62ff27dd7ad347f9fed58fd37964736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"invalidMarketId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"}],\"name\":\"GroupCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"groupId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"name\":\"GroupFinalizing\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"groupId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"marketName\",\"type\":\"string\"}],\"name\":\"GroupMarketAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"name\":\"GroupResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"_marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256[][]\",\"name\":\"_odds\",\"type\":\"uint256[][]\"}],\"name\":\"addOutcomesToGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_winningMarketIndex\",\"type\":\"uint256\"}],\"name\":\"beginResolvingGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"name\":\"finalizeGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"name\":\"getGroup\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Grouped.MarketGroup\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getGroupByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"string[]\",\"name\":\"marketNames\",\"type\":\"string[]\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"internalType\":\"struct Grouped.MarketGroup\",\"name\":\"_group\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"groupCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_groupName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_category\",\"type\":\"string\"}],\"name\":\"initializeGroup\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfMarketGroups\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketGroups\",\"outputs\":[{\"internalType\":\"enum Grouped.GroupStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"invalidMarket\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"invalidMarketName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"endTime\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"category\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"winningMarketIndex\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"resolveMarketAsNo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_groupId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_marketIndexes\",\"type\":\"uint256[]\"}],\"name\":\"resolveMarkets\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/GroupedMarketFactoryV3.sol\":\"GroupedMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/GroupFetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Fetcher.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\n\\nabstract contract GroupFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticGroupBundle {\\n uint256 id;\\n string name;\\n StaticMarketBundle[] markets;\\n string[] marketNames;\\n StaticMarketBundle invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n // Dynamics\\n Grouped.GroupStatus status;\\n }\\n\\n struct DynamicGroupBundle {\\n uint256 id;\\n Grouped.GroupStatus status;\\n DynamicMarketBundle[] markets;\\n DynamicMarketBundle invalidMarket;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticGroupBundle[] memory _groupBundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_groupBundles, _lowestGroupIndex) = buildStaticGroupBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicGroupBundle[] memory _bundles,\\n uint256 _lowestGroupIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestGroupIndex) = buildDynamicGroupBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new StaticGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticGroupBundle(_marketFactory, _ammFactory, _masterChef, _groupIds[i]);\\n }\\n }\\n\\n function buildDynamicGroupBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\\n uint256[] memory _groupIds;\\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\\n\\n _total = _groupIds.length;\\n _bundles = new DynamicGroupBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicGroupBundle(_marketFactory, _ammFactory, _groupIds[i]);\\n }\\n }\\n\\n function buildStaticGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _groupId\\n ) internal view returns (StaticGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.name = _group.name;\\n _bundle.status = _group.status;\\n _bundle.markets = _markets;\\n _bundle.endTime = _group.endTime;\\n _bundle.invalidMarket = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _group.invalidMarket\\n );\\n _bundle.invalidMarketName = _group.invalidMarketName;\\n _bundle.marketNames = _group.marketNames;\\n _bundle.category = _group.category;\\n }\\n\\n function buildDynamicGroupBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _groupId\\n ) internal view returns (DynamicGroupBundle memory _bundle) {\\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_group.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.markets[i]\\n );\\n }\\n\\n _bundle.id = _groupId;\\n _bundle.markets = _markets;\\n _bundle.invalidMarket = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _group.invalidMarket\\n );\\n _bundle.status = _group.status;\\n }\\n\\n // Starts from the end of the groups list because newer groups are more interesting.\\n // _offset is skipping all groups, not just interesting groups\\n function listOfInterestingGroups(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingGroupIds, uint256 _groupIndex) {\\n _interestingGroupIds = new uint256[](_total);\\n\\n uint256 _groupCount = Grouped(_marketFactory).groupCount();\\n\\n // No groups so return nothing. (needed to avoid integer underflow below)\\n if (_groupCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _groupCount;\\n\\n // No remaining groups so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedGroups = 0;\\n _groupIndex = _max - _offset;\\n while (true) {\\n if (_collectedGroups >= _total) break;\\n if (_groupIndex == 0) break;\\n\\n _groupIndex--; // starts out one too high, so this works\\n\\n (Grouped.MarketGroup memory _group, uint256 _groupId) =\\n Grouped(_marketFactory).getGroupByIndex(_groupIndex);\\n\\n if (isGroupInteresting(_group, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingGroupIds[_collectedGroups] = _groupId;\\n _collectedGroups++;\\n }\\n }\\n\\n if (_total > _collectedGroups) {\\n assembly {\\n // shortens array\\n mstore(_interestingGroupIds, _collectedGroups)\\n }\\n }\\n }\\n\\n function isGroupInteresting(Grouped.MarketGroup memory _group, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _group.markets.length; i++) {\\n uint256 _marketId = _group.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n if (openOrHasWinningShares(_marketFactory, _group.invalidMarket)) {\\n return true;\\n }\\n\\n return false;\\n }\\n}\\n\\ncontract GroupedFetcher is GroupFetcher {\\n constructor() Fetcher(\\\"Grouped\\\", \\\"TBD\\\") {}\\n}\\n\",\"keccak256\":\"0xd8cb93eee1737373d56fd149e2bbbf81a3b1b0f6516bfc217acc402105474cfc\",\"license\":\"MIT\"},\"contracts/turbo/Grouped.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./GroupFetcher.sol\\\";\\n\\nabstract contract Grouped is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds {\\n event GroupCreated(uint256 indexed id, uint256 endTime, uint256 invalidMarketId, string invalidMarketName);\\n event GroupMarketAdded(uint256 indexed groupId, uint256 marketId, string marketName);\\n event GroupFinalizing(uint256 indexed groupId, uint256 winningMarketIndex);\\n event GroupResolved(uint256 indexed id, bool valid);\\n\\n enum GroupStatus {Unknown, Scheduled, Finalizing, Final, Invalid}\\n\\n struct MarketGroup {\\n GroupStatus status;\\n string name;\\n uint256[] markets;\\n string[] marketNames;\\n uint256 invalidMarket;\\n string invalidMarketName;\\n uint256 endTime;\\n string category;\\n uint256 winningMarketIndex; // ignore when status is Scheduled. MAX_UINT is invalid\\n }\\n // GroupId => MarketGroup\\n mapping(uint256 => MarketGroup) public marketGroups;\\n uint256[] public listOfMarketGroups;\\n\\n // For regular markets, YES means the team won and NO means the team did not win.\\n // For the invalid market, YES means none of the teams won and NO means a team won.\\n uint256 constant OUTCOME_NO = 0;\\n uint256 constant OUTCOME_YES = 1;\\n\\n uint256 constant MAX_UINT = 2**256 - 1;\\n\\n function groupCount() public view returns (uint256) {\\n return listOfMarketGroups.length;\\n }\\n\\n function getGroup(uint256 _groupId) public view returns (MarketGroup memory) {\\n return marketGroups[_groupId];\\n }\\n\\n function getGroupByIndex(uint256 _index) public view returns (MarketGroup memory _group, uint256 _groupId) {\\n _groupId = listOfMarketGroups[_index];\\n _group = getGroup(_groupId);\\n }\\n\\n function startCreatingMarketGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n uint256 _endTime,\\n string memory _invalidMarketName,\\n string memory _category\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Unknown, \\\"group exists\\\");\\n\\n listOfMarketGroups.push(_groupId);\\n marketGroups[_groupId].status = GroupStatus.Scheduled;\\n marketGroups[_groupId].name = _groupName;\\n marketGroups[_groupId].endTime = _endTime;\\n marketGroups[_groupId].category = _category;\\n\\n uint256 _invalidMarket = startMarket(msg.sender, buildOutcomesNames(_invalidMarketName), invalidOdds(), true);\\n marketGroups[_groupId].invalidMarket = _invalidMarket;\\n marketGroups[_groupId].invalidMarketName = _invalidMarketName;\\n\\n emit GroupCreated(_groupId, _endTime, _invalidMarket, _invalidMarketName);\\n emit GroupMarketAdded(_groupId, _invalidMarket, _invalidMarketName);\\n }\\n\\n function addMarketToMarketGroup(\\n uint256 _groupId,\\n string memory _marketName,\\n uint256[] memory _odds\\n ) internal {\\n require(marketGroups[_groupId].status == GroupStatus.Scheduled, \\\"group must be Scheduled\\\");\\n\\n uint256 _marketId = startMarket(msg.sender, buildOutcomesNames(_marketName), _odds, true);\\n marketGroups[_groupId].markets.push(_marketId);\\n marketGroups[_groupId].marketNames.push(_marketName);\\n emit GroupMarketAdded(_groupId, _marketId, _marketName);\\n }\\n\\n // Use MAX_UINT for _winningMarketIndex to indicate INVALID\\n function startResolvingMarketGroup(uint256 _groupId, uint256 _winningMarketIndex) internal {\\n bool _isInvalid = _winningMarketIndex == MAX_UINT;\\n MarketGroup memory _group = marketGroups[_groupId];\\n\\n require(_group.status == GroupStatus.Scheduled, \\\"group not Scheduled\\\");\\n\\n resolveInvalidMarket(_group, _isInvalid);\\n marketGroups[_groupId].status = GroupStatus.Finalizing;\\n marketGroups[_groupId].winningMarketIndex = _winningMarketIndex;\\n emit GroupFinalizing(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveFinalizingGroupMarket(uint256 _groupId, uint256 _marketIndex) internal {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing, \\\"must be finalizing\\\");\\n\\n uint256 _marketId = _group.markets[_marketIndex];\\n bool _wins = _marketIndex == _group.winningMarketIndex;\\n resolveGroupMarket(_marketId, _wins);\\n }\\n\\n function finalizeMarketGroup(uint256 _groupId) internal {\\n MarketGroup storage _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n bool _valid = _group.winningMarketIndex != MAX_UINT;\\n\\n _group.status = _valid ? GroupStatus.Final : GroupStatus.Invalid;\\n\\n emit GroupResolved(_groupId, _valid);\\n }\\n\\n function resolveGroupMarket(uint256 _marketId, bool _wins) internal {\\n uint256 _winningOutcome = _wins ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_marketId, _winningOutcome);\\n }\\n\\n function resolveInvalidMarket(MarketGroup memory _group, bool _invalid) private {\\n uint256 _outcomeIndex = _invalid ? OUTCOME_YES : OUTCOME_NO;\\n endMarket(_group.invalidMarket, _outcomeIndex);\\n }\\n\\n function buildOutcomesNames(string memory _marketName) internal pure returns (string[] memory _names) {\\n _names = new string[](2);\\n _names[OUTCOME_NO] = string(abi.encodePacked(\\\"NO - \\\", _marketName));\\n _names[OUTCOME_YES] = string(abi.encodePacked(\\\"YES - \\\", _marketName));\\n }\\n\\n function invalidOdds() private pure returns (uint256[] memory _odds) {\\n _odds = new uint256[](2);\\n _odds[OUTCOME_YES] = 1e18;\\n _odds[OUTCOME_NO] = 49e18;\\n }\\n}\\n\",\"keccak256\":\"0x6a6d5b95f52a895fd1bffcdbd0e5a5f4343c085bf7ae8309eb56951f5b50e2ef\",\"license\":\"MIT\"},\"contracts/turbo/GroupedMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./Grouped.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract GroupedMarketFactoryV3 is AbstractMarketFactoryV3, Grouped, ManagedByLink, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {}\\n\\n function initializeGroup(\\n uint256 _groupId,\\n string memory _groupName,\\n string memory _invalidMarketName,\\n uint256 _endTime,\\n string memory _category\\n ) public onlyLinkNode {\\n startCreatingMarketGroup(_groupId, _groupName, _endTime, _invalidMarketName, _category);\\n }\\n\\n function addOutcomesToGroup(\\n uint256 _groupId,\\n string[] memory _marketNames,\\n uint256[][] memory _odds\\n ) public onlyLinkNode {\\n require(_marketNames.length == _odds.length);\\n\\n for (uint256 i = 0; i < _marketNames.length; i++) {\\n addMarketToMarketGroup(_groupId, _marketNames[i], _odds[i]);\\n }\\n }\\n\\n // Set _winner to MAX_UINT (2*256 - 1) to indicate invalid\\n function beginResolvingGroup(uint256 _groupId, uint256 _winningMarketIndex) public onlyLinkNode {\\n startResolvingMarketGroup(_groupId, _winningMarketIndex);\\n }\\n\\n function resolveMarkets(uint256 _groupId, uint256[] memory _marketIndexes) public onlyLinkNode {\\n MarketGroup memory _group = marketGroups[_groupId];\\n require(_group.status == GroupStatus.Finalizing);\\n\\n for (uint256 i = 0; i < _marketIndexes.length; i++) {\\n uint256 _marketIndex = _marketIndexes[i];\\n uint256 _marketId = _group.markets[_marketIndex];\\n if (isMarketResolved(_marketId)) continue; // skip resolved markets\\n resolveFinalizingGroupMarket(_groupId, _marketIndex);\\n }\\n }\\n\\n function finalizeGroup(uint256 _groupId) public onlyLinkNode {\\n finalizeMarketGroup(_groupId);\\n }\\n\\n // Used when some markets in a group can resolve early as NO.\\n // ex: Teams eliminated early from a tournament cannot win the overall tournament.\\n function resolveMarketAsNo(uint256 _marketId) public onlyLinkNode {\\n require(markets[_marketId].active, \\\"market inactive\\\");\\n resolveGroupMarket(_marketId, false);\\n }\\n\\n function getRewardEndTime(uint256 _eventId) public view override returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0x2037f82962a9594e1ebe36e1d7239d967ecef033fa7cc1e9cd20e756f11c191a\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant Spread = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.5.0\\\")\\n ManagedByLink(_linkNode)\\n HasSpreadMarket(Spread, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n makeLine(_homeSpread),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\\n internal\\n returns (uint256[] memory _marketIds)\\n {\\n _marketIds = new uint256[](1);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n }\\n\\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\\n _line = build1Line();\\n _line[0] = addHalfPoint(_homeSpread);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x2187210295b55bd841518dc83cb592ef7365c4d7ba4f38895865e4d26ccefe35\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006007553480156200001657600080fd5b5060405162005ca838038062005ca88339810160408190526200003991620004ec565b604080518082019091526006815265076312e322e360d41b6020820152600080546001600160a01b03808b166001600160a01b03199283163317831617835560018054828c169084161790556009899055600280549189169190921617905582908990899089908990899089908290602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b390620001119086906000199060040162000608565b602060405180830381600087803b1580156200012c57600080fd5b505af115801562000141573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001679190620005df565b50600a62000174620002b5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001cb939285019291909101906200032b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200024d91600984019160209091019062000395565b506101409190910151600a909101805460ff19169115159190911790555050600d80546001600160a01b0319166001600160a01b03969096169590951790945550508251620002a69250600e91506020840190620003d3565b5050505050505050506200063a565b620002bf62000455565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b82805482825590600052602060002090810192821562000383579160200282015b828111156200038357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200034c565b5062000391929150620004c3565b5090565b82805482825590600052602060002090810192821562000383579160200282015b8281111562000383578251825591602001919060010190620003b6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200040b576000855562000383565b82601f106200042657805160ff191683800117855562000383565b8280016001018555821562000383579182018281111562000383578251825591602001919060010190620003b6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003915760008155600101620004c4565b8051620004e78162000621565b919050565b6000806000806000806000610120888a03121562000508578283fd5b8751620005158162000621565b809750506020808901516200052a8162000621565b60408a015160608b01519198509650620005448162000621565b9450609f89018a1362000555578384fd5b604051606081016001600160401b03811182821017156200057257fe5b6040528060808b0160e08c018d8111156200058b578788fd5b875b6003811015620005ac578251845292850192918501916001016200058d565b50839750620005bb81620004da565b96505050505050620005d16101008901620004da565b905092959891949750929550565b600060208284031215620005f1578081fd5b8151801515811462000601578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200063757600080fd5b50565b61565e806200064a6000396000f3fe60806040523480156200001157600080fd5b50600436106200028c5760003560e01c8063808e24181162000165578063cc87adea11620000d5578063dc9024da1162000093578063dc9024da1462000588578063e2c30b15146200059f578063e5678dfa14620005b6578063eb44fdd314620005cd578063ec97908214620005f3578063f2fde38b14620005fd576200028c565b8063cc87adea1462000520578063ceb606541462000537578063d4b6838e146200055d578063d5da4f1d1462000567578063d8dfeb45146200057e576200028c565b80638f23b32611620001235780638f23b32614620004d457806397eef18714620004de578063992c907914620004f5578063a544a62c146200050c578063b0e21e8a1462000516576200028c565b8063808e2418146200047b578063893d20e814620004925780638bdb957f146200049c5780638ce7442614620004b35780638e0ed19314620004bd576200028c565b806349a4d93411620002015780635653395111620001bf57806356533951146200040d5780637391b6d014620004395780637641ab011462000450578063787dce3d146200045a5780637d1d7fb81462000471576200028c565b806349a4d93414620003a35780634a7d036914620003ba5780634b2d9ffc14620003c45780634c9f66c714620003ce57806353ac55f514620003e7576200028c565b80633037faf1116200024f5780633037faf1146200031157806332ecabe9146200033857806335a9cdad146200034f57806342e0ed161462000375578063473a6d52146200038c576200028c565b80630a18a4aa14620002915780630d8e6e2c14620002aa57806319b5068714620002cc578063221fff8114620002e35780633025077b14620002fa575b600080fd5b620002a8620002a236600462003ca5565b62000614565b005b620002b46200063c565b604051620002c391906200400b565b60405180910390f35b620002a8620002dd36600462003a9b565b620006d6565b620002a8620002f436600462003cc7565b6200074b565b620002a86200030b36600462003c03565b62000a78565b620003286200032236600462003a9b565b62000aa6565b604051620002c392919062004181565b620002a86200034936600462003973565b62000adf565b620003666200036036600462003cc7565b62000b2d565b604051620002c3919062004276565b620003666200038636600462003a9b565b62000f66565b620003666200039d36600462003a9b565b62000f6e565b62000366620003b436600462003956565b62000faa565b6200036662000fbc565b6200036662001086565b620003d86200108c565b604051620002c3919062003f40565b620003fe620003f836600462003a9b565b6200109b565b604051620002c3919062003f91565b620004246200041e36600462003a9b565b62001225565b604051620002c3979695949392919062003f9c565b620002a86200044a36600462003af2565b62001413565b620003666200148b565b620002a86200046b36600462003a9b565b62001491565b62000366620014ae565b620003666200048c36600462003a9b565b620014b4565b620003d8620014d6565b620002a8620004ad36600462003a9b565b620014e5565b620003d862001508565b62000366620004ce36600462003956565b62001517565b62000366620015d3565b620002a8620004ef36600462003a9b565b620015d9565b620003666200050636600462003acd565b620015f6565b6200036662001a0f565b6200036662001a15565b620003666200053136600462003a9b565b62001a1b565b6200054e6200054836600462003a9b565b62001a22565b604051620002c391906200416c565b620003d862001d9c565b620002a86200057836600462003a9b565b62001dab565b620003d862001dc8565b620002a86200059936600462003bba565b62001dd7565b620002a8620005b036600462003956565b620021ea565b62000366620005c7366004620039ae565b62002256565b620005e4620005de36600462003a9b565b620022a4565b604051620002c39190620041a5565b6200036662002443565b620003fe6200060e36600462003956565b62002449565b600d546001600160a01b031633146200062c57600080fd5b620006388282620024b3565b5050565b600e8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006cc5780601f10620006a057610100808354040283529160200191620006cc565b820191906000526020600020905b815481529060010190602001808311620006ae57829003601f168201915b5050505050905090565b600d546001600160a01b03163314620006ee57600080fd5b600a8181548110620006fc57fe5b60009182526020909120600a600b90920201015460ff166200073b5760405162461bcd60e51b8152600401620007329062004118565b60405180910390fd5b62000748816000620028c5565b50565b600a5483106200075a57600080fd5b600a83815481106200076857fe5b60009182526020909120600a600b90920201015460ff166200078957600080fd5b6000620007968362000f6e565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007cd9033903090869060040162003f54565b602060405180830381600087803b158015620007e857600080fd5b505af1158015620007fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000823919062003a00565b506000600a85815481106200083457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620008b857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000899575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200097d57602002820191906000526020600020905b81548152602001906001019080831162000968575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000a335781602001518181518110620009bb57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b8152600401620009f292919062003f78565b600060405180830381600087803b15801562000a0d57600080fd5b505af115801562000a22573d6000803e3d6000fd5b5050600190920191506200099c9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f285858560405162000a699392919062004350565b60405180910390a15050505050565b600d546001600160a01b0316331462000a9057600080fd5b62000a9f8585848685620028eb565b5050505050565b62000ab062003612565b6000600c838154811062000ac057fe5b9060005260206000200154905062000ad88162001a22565b9150915091565b6000546001600160a01b0316331462000af757600080fd5b801562000b0a5762000b0862000fbc565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000b3f57600080fd5b600a848154811062000b4d57fe5b60009182526020909120600a600b90920201015460ff1662000b6e57600080fd5b6000600a858154811062000b7e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000c0257602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000be3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000cc757602002820191906000526020600020905b81548152602001906001019080831162000cb2575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000d7d578160200151818151811062000d0557fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000d3c92919062003f78565b600060405180830381600087803b15801562000d5757600080fd5b505af115801562000d6c573d6000803e3d6000fd5b50506001909201915062000ce69050565b50600062000d8b8562000f6e565b9050600062000dbc670de0b6b3a764000062000db58560a001518562002a9290919063ffffffff16565b9062002ac4565b9050600062000de6670de0b6b3a764000062000db58660c001518662002a9290919063ffffffff16565b905062000e008162000df9858562002ada565b9062002ada565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000e3d908990879060040162003f78565b602060405180830381600087803b15801562000e5857600080fd5b505af115801562000e6d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e93919062003a00565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000ec690849060040162004276565b602060405180830381600087803b15801562000ee157600080fd5b505af115801562000ef6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f1c919062003a00565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000f529392919062004350565b60405180910390a150909695505050505050565b60005b919050565b6000600954821015801562000f8d5750600954828162000f8a57fe5b06155b62000f9757600080fd5b600954828162000fa357fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000fd857503330145b62000fe257600080fd5b60075480156200108157600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926200102992911690859060040162003f78565b602060405180830381600087803b1580156200104457600080fd5b505af115801562001059573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200107f919062003a00565b505b905090565b60035481565b6002546001600160a01b031681565b600080600a8381548110620010ac57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200113057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001111575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011f557602002820191906000526020600020905b815481526020019060010190808311620011e0575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b600b602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f810186900486028301860190965285825260ff909216949293909290830182828015620012cd5780601f10620012a157610100808354040283529160200191620012cd565b820191906000526020600020905b815481529060010190602001808311620012af57829003601f168201915b50505050600483015460058401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620013685780601f106200133c5761010080835404028352916020019162001368565b820191906000526020600020905b8154815290600101906020018083116200134a57829003601f168201915b50505050600683015460078401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620014035780601f10620013d75761010080835404028352916020019162001403565b820191906000526020600020905b815481529060010190602001808311620013e557829003601f168201915b5050505050908060080154905087565b600d546001600160a01b031633146200142b57600080fd5b80518251146200143a57600080fd5b60005b825181101562001485576200147c848483815181106200145957fe5b60200260200101518484815181106200146e57fe5b602002602001015162002af0565b6001016200143d565b50505050565b60095481565b6000546001600160a01b03163314620014a957600080fd5b600555565b60045481565b600c8181548110620014c557600080fd5b600091825260209091200154905081565b6000546001600160a01b031690565b600d546001600160a01b03163314620014fd57600080fd5b620007488162002bd0565b6006546001600160a01b031681565b336000908152600860205260408120548015620015cd573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001575908690859060040162003f78565b602060405180830381600087803b1580156200159057600080fd5b505af1158015620015a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015cb919062003a00565b505b92915050565b600c5490565b6000546001600160a01b03163314620015f157600080fd5b600355565b600062001603836200109b565b620016225760405162461bcd60e51b8152600401620007329062004141565b6000600a84815481106200163257fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620016b657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001697575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200177b57602002820191906000526020600020905b81548152602001906001019080831162001766575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b0390911690637129778490620017cf90339060040162003f40565b602060405180830381600087803b158015620017ea57600080fd5b505af1158015620017ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001825919062003ab4565b905060095460095482816200183657fe5b040290506000620018478262000f6e565b9050600062001871670de0b6b3a764000062000db586608001518562002a9290919063ffffffff16565b90506200187f828262002ada565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb90620018ce908990869060040162003f78565b602060405180830381600087803b158015620018e957600080fd5b505af1158015620018fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001924919062003a00565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200196e57600080fd5b505afa15801562001983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620019ad919081019062003a1f565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b604051620019fa9796959493929190620042b8565b60405180910390a25091979650505050505050565b60075481565b60055481565b6009540290565b62001a2c62003612565b6000828152600b602052604090819020815161012081019092528054829060ff16600481111562001a5957fe5b600481111562001a6557fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001b065780601f1062001ada5761010080835404028352916020019162001b06565b820191906000526020600020905b81548152906001019060200180831162001ae857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001b6057602002820191906000526020600020905b81548152602001906001019080831162001b4b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562001c3f5760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001c2a5780601f1062001bfe5761010080835404028352916020019162001c2a565b820191906000526020600020905b81548152906001019060200180831162001c0c57829003601f168201915b50505050508152602001906001019062001b8e565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001ce05780601f1062001cb45761010080835404028352916020019162001ce0565b820191906000526020600020905b81548152906001019060200180831162001cc257829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001d825780601f1062001d565761010080835404028352916020019162001d82565b820191906000526020600020905b81548152906001019060200180831162001d6457829003601f168201915b505050505081526020016008820154815250509050919050565b600d546001600160a01b031681565b6000546001600160a01b0316331462001dc357600080fd5b600455565b6001546001600160a01b031681565b600d546001600160a01b0316331462001def57600080fd5b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562001e1b57fe5b600481111562001e2757fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001ec85780601f1062001e9c5761010080835404028352916020019162001ec8565b820191906000526020600020905b81548152906001019060200180831162001eaa57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001f2257602002820191906000526020600020905b81548152602001906001019080831162001f0d575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620020015760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001fec5780601f1062001fc05761010080835404028352916020019162001fec565b820191906000526020600020905b81548152906001019060200180831162001fce57829003601f168201915b50505050508152602001906001019062001f50565b50505090825250600482015460208083019190915260058301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620020a25780601f106200207657610100808354040283529160200191620020a2565b820191906000526020600020905b8154815290600101906020018083116200208457829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620021445780601f10620021185761010080835404028352916020019162002144565b820191906000526020600020905b8154815290600101906020018083116200212657829003601f168201915b50505091835250506008919091015460209091015290506002815160048111156200216b57fe5b146200217657600080fd5b60005b8251811015620014855760008382815181106200219257fe5b60200260200101519050600083604001518281518110620021af57fe5b60200260200101519050620021c4816200109b565b15620021d2575050620021e1565b620021de868362002c72565b50505b60010162002179565b6000546001600160a01b031633146200220257600080fd5b600d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b84518110156200229c5762002291620022898683815181106200227a57fe5b602002602001015186620015f6565b839062003043565b91506001016200225b565b509392505050565b620022ae6200365f565b600a548210620022ca57620022c262003056565b905062000f69565b600a8281548110620022d857fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200233d575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200242157602002820191906000526020600020905b8154815260200190600101908083116200240c575b5050509183525050600a919091015460ff161515602090910152905062000f69565b600a5490565b600080546001600160a01b031633146200246257600080fd5b6001600160a01b0382166200247657600080fd5b6000546200248e906001600160a01b03168362000638565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6000828152600b6020526040808220815161012081019092528054600019851493929190829060ff166004811115620024e857fe5b6004811115620024f457fe5b8152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620025955780601f10620025695761010080835404028352916020019162002595565b820191906000526020600020905b8154815290600101906020018083116200257757829003601f168201915b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620025ef57602002820191906000526020600020905b815481526020019060010190808311620025da575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620026ce5760008481526020908190208301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015620026b95780601f106200268d57610100808354040283529160200191620026b9565b820191906000526020600020905b8154815290600101906020018083116200269b57829003601f168201915b5050505050815260200190600101906200261d565b50505090825250600482015460208083019190915260058301805460408051601f600260001961010060018716150201909416939093049283018590048502810185018252828152940193928301828280156200276f5780601f1062002743576101008083540402835291602001916200276f565b820191906000526020600020905b8154815290600101906020018083116200275157829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620028115780601f10620027e55761010080835404028352916020019162002811565b820191906000526020600020905b815481529060010190602001808311620027f357829003601f168201915b50505091835250506008919091015460209091015290506001815160048111156200283857fe5b14620028585760405162461bcd60e51b8152600401620007329062004062565b620028648183620030cc565b6000848152600b602052604090819020805460ff191660021781556008018490555184907f6b437d58f4403cecb2353bf3e8f2384a91e7518f0a2b0e6762b0425b5e6c462190620028b790869062004276565b60405180910390a250505050565b600081620028d5576000620028d8565b60015b9050620028e68382620030ec565b505050565b6000858152600b602052604081205460ff1660048111156200290957fe5b14620029295760405162461bcd60e51b815260040162000732906200408f565b600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018690556000868152600b60209081526040909120805460ff19168317815586516200298a939190910191870190620036cd565b506000858152600b60209081526040909120600681018590558251620029b992600790920191840190620036cd565b506000620029de33620029cc8562003215565b620029d6620032be565b600162003328565b6000878152600b6020908152604090912060048101839055855192935062002a0f92600590910191860190620036cd565b50857fb4838dfe8d568d0b67fdac2db628f206c6ee584b385d7567e743755db005d00285838660405162002a46939291906200436f565b60405180910390a2857f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a6319828560405162002a8292919062004335565b60405180910390a2505050505050565b60008262002aa357506000620015cd565b8282028284828162002ab157fe5b041462002abd57600080fd5b9392505050565b60008082848162002ad157fe5b04949350505050565b60008282111562002aea57600080fd5b50900390565b60016000848152600b602052604090205460ff16600481111562002b1057fe5b1462002b305760405162461bcd60e51b81526004016200073290620040e1565b600062002b4b3362002b428562003215565b84600162003328565b6000858152600b6020908152604082206002810180546001818101835591855283852001859055600390910180549182018155835291819020865193945062002b9b9392019190860190620036cd565b50837f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a63198285604051620028b792919062004335565b6000818152600b602052604090206002815460ff16600481111562002bf157fe5b1462002bfc57600080fd5b600881015460001914158062002c1457600462002c17565b60035b8254839060ff1916600183600481111562002c2e57fe5b0217905550827f8b6ba55ee795a338c4c907ef43b3a72613c96c34ae6fce3131933cbf59ed4b638260405162002c65919062003f91565b60405180910390a2505050565b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562002c9e57fe5b600481111562002caa57fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562002d4b5780601f1062002d1f5761010080835404028352916020019162002d4b565b820191906000526020600020905b81548152906001019060200180831162002d2d57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562002da557602002820191906000526020600020905b81548152602001906001019080831162002d90575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562002e845760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562002e6f5780601f1062002e435761010080835404028352916020019162002e6f565b820191906000526020600020905b81548152906001019060200180831162002e5157829003601f168201915b50505050508152602001906001019062002dd3565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002f255780601f1062002ef95761010080835404028352916020019162002f25565b820191906000526020600020905b81548152906001019060200180831162002f0757829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002fc75780601f1062002f9b5761010080835404028352916020019162002fc7565b820191906000526020600020905b81548152906001019060200180831162002fa957829003601f168201915b505050918352505060089190910154602090910152905060028151600481111562002fee57fe5b146200300e5760405162461bcd60e51b81526004016200073290620040b5565b6000816040015183815181106200302157fe5b6020026020010151905060008261010001518414905062000a9f8282620028c5565b60008282018381101562002abd57600080fd5b620030606200365f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600081620030dc576000620030df565b60015b9050620028e68360800151825b6000600a8381548110620030fc57fe5b90600052602060002090600b0201905060008160010183815481106200311e57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b1580156200319d57600080fd5b505afa158015620031b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031dc919081019062003a1f565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f8583868460405162000a6994939291906200427f565b6040805160028082526060828101909352816020015b60608152602001906001900390816200322b5790505090508160405160200162003256919062003f11565b604051602081830303815290604052816000815181106200327357fe5b60200260200101819052508160405160200162003291919062003ee1565b60405160208183030381529060405281600181518110620032ae57fe5b6020026020010181905250919050565b6040805160028082526060808301845292602083019080368337019050509050670de0b6b3a764000081600181518110620032f557fe5b6020026020010181815250506802a802f8630a240000816000815181106200331957fe5b60200260200101818152505090565b600a80546040805161016081019091526001600160a01b0387168152909190602081016200335787306200351d565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033f79392850192919091019062003762565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003479916009840191602090910190620037ba565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620034cc9083908790879062004306565b60405180910390a1811562003515577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200350c919062004276565b60405180910390a15b949350505050565b815160609060008167ffffffffffffffff811180156200353c57600080fd5b5060405190808252806020026020018201604052801562003567578160200160208202803683370190505b50905060005b8281101562003609578581815181106200358357fe5b60200260200101518682815181106200359857fe5b602002602001015186604051620035af90620037f7565b620035bd9392919062004020565b604051809103906000f080158015620035da573d6000803e3d6000fd5b50828281518110620035e857fe5b6001600160a01b03909216602092830291909101909101526001016200356d565b50949350505050565b604080516101208101909152806000815260200160608152602001606081526020016060815260200160008152602001606081526020016000815260200160608152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262003705576000855562003750565b82601f106200372057805160ff191683800117855562003750565b8280016001018555821562003750579182015b828111156200375057825182559160200191906001019062003733565b506200375e92915062003805565b5090565b82805482825590600052602060002090810192821562003750579160200282015b828111156200375057825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003783565b8280548282559060005260206000209081019282156200375057916020028201828111156200375057825182559160200191906001019062003733565b6111f3806200443683390190565b5b808211156200375e576000815560010162003806565b80356001600160a01b038116811462000f6957600080fd5b600082601f83011262003845578081fd5b813560206200385e6200385883620043b5565b62004390565b82815281810190858301855b85811015620038975762003884898684358b0101620038a4565b845292840192908401906001016200386a565b5090979650505050505050565b600082601f830112620038b5578081fd5b81356020620038c86200385883620043b5565b8281528181019085830183850287018401881015620038e5578586fd5b855b858110156200389757813584529284019290840190600101620038e7565b600082601f83011262003916578081fd5b8135620039276200385882620043d4565b8181528460208386010111156200393c578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003968578081fd5b62002abd826200381c565b6000806040838503121562003986578081fd5b62003991836200381c565b91506020830135620039a38162004426565b809150509250929050565b60008060408385031215620039c1578182fd5b823567ffffffffffffffff811115620039d8578283fd5b620039e685828601620038a4565b925050620039f7602084016200381c565b90509250929050565b60006020828403121562003a12578081fd5b815162002abd8162004426565b60006020828403121562003a31578081fd5b815167ffffffffffffffff81111562003a48578182fd5b8201601f8101841362003a59578182fd5b805162003a6a6200385882620043d4565b81815285602083850101111562003a7f578384fd5b62003a92826020830160208601620043f7565b95945050505050565b60006020828403121562003aad578081fd5b5035919050565b60006020828403121562003ac6578081fd5b5051919050565b6000806040838503121562003ae0578182fd5b82359150620039f7602084016200381c565b60008060006060848603121562003b07578081fd5b8335925060208085013567ffffffffffffffff8082111562003b27578384fd5b818701915087601f83011262003b3b578384fd5b813562003b4c6200385882620043b5565b81815284810190848601875b8481101562003b855762003b728d8984358a010162003905565b8452928701929087019060010162003b58565b50909750505050604087013592508083111562003ba0578384fd5b505062003bb08682870162003834565b9150509250925092565b6000806040838503121562003bcd578182fd5b82359150602083013567ffffffffffffffff81111562003beb578182fd5b62003bf985828601620038a4565b9150509250929050565b600080600080600060a0868803121562003c1b578283fd5b85359450602086013567ffffffffffffffff8082111562003c3a578485fd5b62003c4889838a0162003905565b9550604088013591508082111562003c5e578485fd5b62003c6c89838a0162003905565b945060608801359350608088013591508082111562003c89578283fd5b5062003c988882890162003905565b9150509295509295909350565b6000806040838503121562003cb8578182fd5b50508035926020909101359150565b60008060006060848603121562003cdc578081fd5b833592506020840135915062003cf5604085016200381c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d455781516001600160a01b03168752958201959082019060010162003d1e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101562003d9a57828403895262003d8784835162003ded565b9885019893509084019060010162003d6c565b5091979650505050505050565b6000815180845260208085019450808401835b8381101562003d455781518752958201959082019060010162003dba565b15159052565b6005811062003de957fe5b9052565b6000815180845262003e07816020860160208601620043f7565b601f01601f19169290920160200192915050565b600061012062003e2d84845162003dde565b602083015181602086015262003e468286018262003ded565b9150506040830151848203604086015262003e62828262003da7565b9150506060830151848203606086015262003e7e828262003d50565b9150506080830151608085015260a083015184820360a086015262003ea4828262003ded565b91505060c083015160c085015260e083015184820360e086015262003eca828262003ded565b610100948501519590940194909452509092915050565b60006502ca2a99016960d51b8252825162003f04816006850160208701620043f7565b9190910160060192915050565b600064027279016960dd1b8252825162003f33816005850160208701620043f7565b9190910160050192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600062003faa828a62003dde565b60e0602083015262003fc060e083018962003ded565b876040840152828103606084015262003fda818862003ded565b905085608084015282810360a084015262003ff6818662003ded565b9150508260c083015298975050505050505050565b60006020825262002abd602083018462003ded565b60006060825262004035606083018662003ded565b828103602084015262004049818662003ded565b91505060018060a01b0383166040830152949350505050565b60208082526013908201527219dc9bdd5c081b9bdd0814d8da19591d5b1959606a1b604082015260600190565b6020808252600c908201526b67726f75702065786973747360a01b604082015260600190565b6020808252601290820152716d7573742062652066696e616c697a696e6760701b604082015260600190565b60208082526017908201527f67726f7570206d757374206265205363686564756c6564000000000000000000604082015260600190565b6020808252600f908201526e6d61726b657420696e61637469766560881b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262002abd602083018462003e1b565b60006040825262004196604083018562003e1b565b90508260208301529392505050565b600060208252620041bb60208301845162003cfe565b6020830151610160806040850152620041d961018085018362003d0b565b91506040850151620041ef606086018262003cfe565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262004255848362003da7565b9350808701519150506200426c8286018262003dd8565b5090949350505050565b90815260200190565b600085825260018060a01b038516602083015283604083015260806060830152620042ae608083018462003ded565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e06060830152620042e760e083018762003ded565b60808301959095525060a081019290925260c090910152949350505050565b60008482526060602083015262004321606083018562003d50565b8281036040840152620042ae818562003da7565b60008382526040602083015262003515604083018462003ded565b92835260208301919091526001600160a01b0316604082015260600190565b60008482528360208301526060604083015262003a92606083018462003ded565b60405181810167ffffffffffffffff81118282101715620043ad57fe5b604052919050565b600067ffffffffffffffff821115620043ca57fe5b5060209081020190565b600067ffffffffffffffff821115620043e957fe5b50601f01601f191660200190565b60005b8381101562004414578181015183820152602001620043fa565b83811115620014855750506000910152565b80151581146200074857600080fdfe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220c3947cfe91c803dfb4c46fbb35412f3e9f7e7d04150213810330f28c9192c19f64736f6c63430007060033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b50600436106200028c5760003560e01c8063808e24181162000165578063cc87adea11620000d5578063dc9024da1162000093578063dc9024da1462000588578063e2c30b15146200059f578063e5678dfa14620005b6578063eb44fdd314620005cd578063ec97908214620005f3578063f2fde38b14620005fd576200028c565b8063cc87adea1462000520578063ceb606541462000537578063d4b6838e146200055d578063d5da4f1d1462000567578063d8dfeb45146200057e576200028c565b80638f23b32611620001235780638f23b32614620004d457806397eef18714620004de578063992c907914620004f5578063a544a62c146200050c578063b0e21e8a1462000516576200028c565b8063808e2418146200047b578063893d20e814620004925780638bdb957f146200049c5780638ce7442614620004b35780638e0ed19314620004bd576200028c565b806349a4d93411620002015780635653395111620001bf57806356533951146200040d5780637391b6d014620004395780637641ab011462000450578063787dce3d146200045a5780637d1d7fb81462000471576200028c565b806349a4d93414620003a35780634a7d036914620003ba5780634b2d9ffc14620003c45780634c9f66c714620003ce57806353ac55f514620003e7576200028c565b80633037faf1116200024f5780633037faf1146200031157806332ecabe9146200033857806335a9cdad146200034f57806342e0ed161462000375578063473a6d52146200038c576200028c565b80630a18a4aa14620002915780630d8e6e2c14620002aa57806319b5068714620002cc578063221fff8114620002e35780633025077b14620002fa575b600080fd5b620002a8620002a236600462003ca5565b62000614565b005b620002b46200063c565b604051620002c391906200400b565b60405180910390f35b620002a8620002dd36600462003a9b565b620006d6565b620002a8620002f436600462003cc7565b6200074b565b620002a86200030b36600462003c03565b62000a78565b620003286200032236600462003a9b565b62000aa6565b604051620002c392919062004181565b620002a86200034936600462003973565b62000adf565b620003666200036036600462003cc7565b62000b2d565b604051620002c3919062004276565b620003666200038636600462003a9b565b62000f66565b620003666200039d36600462003a9b565b62000f6e565b62000366620003b436600462003956565b62000faa565b6200036662000fbc565b6200036662001086565b620003d86200108c565b604051620002c3919062003f40565b620003fe620003f836600462003a9b565b6200109b565b604051620002c3919062003f91565b620004246200041e36600462003a9b565b62001225565b604051620002c3979695949392919062003f9c565b620002a86200044a36600462003af2565b62001413565b620003666200148b565b620002a86200046b36600462003a9b565b62001491565b62000366620014ae565b620003666200048c36600462003a9b565b620014b4565b620003d8620014d6565b620002a8620004ad36600462003a9b565b620014e5565b620003d862001508565b62000366620004ce36600462003956565b62001517565b62000366620015d3565b620002a8620004ef36600462003a9b565b620015d9565b620003666200050636600462003acd565b620015f6565b6200036662001a0f565b6200036662001a15565b620003666200053136600462003a9b565b62001a1b565b6200054e6200054836600462003a9b565b62001a22565b604051620002c391906200416c565b620003d862001d9c565b620002a86200057836600462003a9b565b62001dab565b620003d862001dc8565b620002a86200059936600462003bba565b62001dd7565b620002a8620005b036600462003956565b620021ea565b62000366620005c7366004620039ae565b62002256565b620005e4620005de36600462003a9b565b620022a4565b604051620002c39190620041a5565b6200036662002443565b620003fe6200060e36600462003956565b62002449565b600d546001600160a01b031633146200062c57600080fd5b620006388282620024b3565b5050565b600e8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006cc5780601f10620006a057610100808354040283529160200191620006cc565b820191906000526020600020905b815481529060010190602001808311620006ae57829003601f168201915b5050505050905090565b600d546001600160a01b03163314620006ee57600080fd5b600a8181548110620006fc57fe5b60009182526020909120600a600b90920201015460ff166200073b5760405162461bcd60e51b8152600401620007329062004118565b60405180910390fd5b62000748816000620028c5565b50565b600a5483106200075a57600080fd5b600a83815481106200076857fe5b60009182526020909120600a600b90920201015460ff166200078957600080fd5b6000620007968362000f6e565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007cd9033903090869060040162003f54565b602060405180830381600087803b158015620007e857600080fd5b505af1158015620007fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000823919062003a00565b506000600a85815481106200083457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620008b857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000899575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200097d57602002820191906000526020600020905b81548152602001906001019080831162000968575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000a335781602001518181518110620009bb57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b8152600401620009f292919062003f78565b600060405180830381600087803b15801562000a0d57600080fd5b505af115801562000a22573d6000803e3d6000fd5b5050600190920191506200099c9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f285858560405162000a699392919062004350565b60405180910390a15050505050565b600d546001600160a01b0316331462000a9057600080fd5b62000a9f8585848685620028eb565b5050505050565b62000ab062003612565b6000600c838154811062000ac057fe5b9060005260206000200154905062000ad88162001a22565b9150915091565b6000546001600160a01b0316331462000af757600080fd5b801562000b0a5762000b0862000fbc565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000b3f57600080fd5b600a848154811062000b4d57fe5b60009182526020909120600a600b90920201015460ff1662000b6e57600080fd5b6000600a858154811062000b7e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000c0257602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000be3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000cc757602002820191906000526020600020905b81548152602001906001019080831162000cb2575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000d7d578160200151818151811062000d0557fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000d3c92919062003f78565b600060405180830381600087803b15801562000d5757600080fd5b505af115801562000d6c573d6000803e3d6000fd5b50506001909201915062000ce69050565b50600062000d8b8562000f6e565b9050600062000dbc670de0b6b3a764000062000db58560a001518562002a9290919063ffffffff16565b9062002ac4565b9050600062000de6670de0b6b3a764000062000db58660c001518662002a9290919063ffffffff16565b905062000e008162000df9858562002ada565b9062002ada565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000e3d908990879060040162003f78565b602060405180830381600087803b15801562000e5857600080fd5b505af115801562000e6d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000e93919062003a00565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000ec690849060040162004276565b602060405180830381600087803b15801562000ee157600080fd5b505af115801562000ef6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f1c919062003a00565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000f529392919062004350565b60405180910390a150909695505050505050565b60005b919050565b6000600954821015801562000f8d5750600954828162000f8a57fe5b06155b62000f9757600080fd5b600954828162000fa357fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000fd857503330145b62000fe257600080fd5b60075480156200108157600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb926200102992911690859060040162003f78565b602060405180830381600087803b1580156200104457600080fd5b505af115801562001059573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200107f919062003a00565b505b905090565b60035481565b6002546001600160a01b031681565b600080600a8381548110620010ac57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200113057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001111575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011f557602002820191906000526020600020905b815481526020019060010190808311620011e0575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b600b602090815260009182526040918290208054600180830180548651600261010094831615949094026000190190911692909204601f810186900486028301860190965285825260ff909216949293909290830182828015620012cd5780601f10620012a157610100808354040283529160200191620012cd565b820191906000526020600020905b815481529060010190602001808311620012af57829003601f168201915b50505050600483015460058401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620013685780601f106200133c5761010080835404028352916020019162001368565b820191906000526020600020905b8154815290600101906020018083116200134a57829003601f168201915b50505050600683015460078401805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529596939593945090830182828015620014035780601f10620013d75761010080835404028352916020019162001403565b820191906000526020600020905b815481529060010190602001808311620013e557829003601f168201915b5050505050908060080154905087565b600d546001600160a01b031633146200142b57600080fd5b80518251146200143a57600080fd5b60005b825181101562001485576200147c848483815181106200145957fe5b60200260200101518484815181106200146e57fe5b602002602001015162002af0565b6001016200143d565b50505050565b60095481565b6000546001600160a01b03163314620014a957600080fd5b600555565b60045481565b600c8181548110620014c557600080fd5b600091825260209091200154905081565b6000546001600160a01b031690565b600d546001600160a01b03163314620014fd57600080fd5b620007488162002bd0565b6006546001600160a01b031681565b336000908152600860205260408120548015620015cd573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001575908690859060040162003f78565b602060405180830381600087803b1580156200159057600080fd5b505af1158015620015a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620015cb919062003a00565b505b92915050565b600c5490565b6000546001600160a01b03163314620015f157600080fd5b600355565b600062001603836200109b565b620016225760405162461bcd60e51b8152600401620007329062004141565b6000600a84815481106200163257fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620016b657602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001697575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200177b57602002820191906000526020600020905b81548152602001906001019080831162001766575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b0390911690637129778490620017cf90339060040162003f40565b602060405180830381600087803b158015620017ea57600080fd5b505af1158015620017ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001825919062003ab4565b905060095460095482816200183657fe5b040290506000620018478262000f6e565b9050600062001871670de0b6b3a764000062000db586608001518562002a9290919063ffffffff16565b90506200187f828262002ada565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb90620018ce908990869060040162003f78565b602060405180830381600087803b158015620018e957600080fd5b505af1158015620018fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001924919062003a00565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200196e57600080fd5b505afa15801562001983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620019ad919081019062003a1f565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b604051620019fa9796959493929190620042b8565b60405180910390a25091979650505050505050565b60075481565b60055481565b6009540290565b62001a2c62003612565b6000828152600b602052604090819020815161012081019092528054829060ff16600481111562001a5957fe5b600481111562001a6557fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001b065780601f1062001ada5761010080835404028352916020019162001b06565b820191906000526020600020905b81548152906001019060200180831162001ae857829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001b6057602002820191906000526020600020905b81548152602001906001019080831162001b4b575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562001c3f5760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001c2a5780601f1062001bfe5761010080835404028352916020019162001c2a565b820191906000526020600020905b81548152906001019060200180831162001c0c57829003601f168201915b50505050508152602001906001019062001b8e565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001ce05780601f1062001cb45761010080835404028352916020019162001ce0565b820191906000526020600020905b81548152906001019060200180831162001cc257829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562001d825780601f1062001d565761010080835404028352916020019162001d82565b820191906000526020600020905b81548152906001019060200180831162001d6457829003601f168201915b505050505081526020016008820154815250509050919050565b600d546001600160a01b031681565b6000546001600160a01b0316331462001dc357600080fd5b600455565b6001546001600160a01b031681565b600d546001600160a01b0316331462001def57600080fd5b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562001e1b57fe5b600481111562001e2757fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001ec85780601f1062001e9c5761010080835404028352916020019162001ec8565b820191906000526020600020905b81548152906001019060200180831162001eaa57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001f2257602002820191906000526020600020905b81548152602001906001019080831162001f0d575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620020015760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562001fec5780601f1062001fc05761010080835404028352916020019162001fec565b820191906000526020600020905b81548152906001019060200180831162001fce57829003601f168201915b50505050508152602001906001019062001f50565b50505090825250600482015460208083019190915260058301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620020a25780601f106200207657610100808354040283529160200191620020a2565b820191906000526020600020905b8154815290600101906020018083116200208457829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620021445780601f10620021185761010080835404028352916020019162002144565b820191906000526020600020905b8154815290600101906020018083116200212657829003601f168201915b50505091835250506008919091015460209091015290506002815160048111156200216b57fe5b146200217657600080fd5b60005b8251811015620014855760008382815181106200219257fe5b60200260200101519050600083604001518281518110620021af57fe5b60200260200101519050620021c4816200109b565b15620021d2575050620021e1565b620021de868362002c72565b50505b60010162002179565b6000546001600160a01b031633146200220257600080fd5b600d80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b84518110156200229c5762002291620022898683815181106200227a57fe5b602002602001015186620015f6565b839062003043565b91506001016200225b565b509392505050565b620022ae6200365f565b600a548210620022ca57620022c262003056565b905062000f69565b600a8281548110620022d857fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200233d575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200242157602002820191906000526020600020905b8154815260200190600101908083116200240c575b5050509183525050600a919091015460ff161515602090910152905062000f69565b600a5490565b600080546001600160a01b031633146200246257600080fd5b6001600160a01b0382166200247657600080fd5b6000546200248e906001600160a01b03168362000638565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6000828152600b6020526040808220815161012081019092528054600019851493929190829060ff166004811115620024e857fe5b6004811115620024f457fe5b8152602001600182018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620025955780601f10620025695761010080835404028352916020019162002595565b820191906000526020600020905b8154815290600101906020018083116200257757829003601f168201915b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620025ef57602002820191906000526020600020905b815481526020019060010190808311620025da575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b82821015620026ce5760008481526020908190208301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015620026b95780601f106200268d57610100808354040283529160200191620026b9565b820191906000526020600020905b8154815290600101906020018083116200269b57829003601f168201915b5050505050815260200190600101906200261d565b50505090825250600482015460208083019190915260058301805460408051601f600260001961010060018716150201909416939093049283018590048502810185018252828152940193928301828280156200276f5780601f1062002743576101008083540402835291602001916200276f565b820191906000526020600020905b8154815290600101906020018083116200275157829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f60026000196101006001871615020190941693909304928301859004850281018501825282815294019392830182828015620028115780601f10620027e55761010080835404028352916020019162002811565b820191906000526020600020905b815481529060010190602001808311620027f357829003601f168201915b50505091835250506008919091015460209091015290506001815160048111156200283857fe5b14620028585760405162461bcd60e51b8152600401620007329062004062565b620028648183620030cc565b6000848152600b602052604090819020805460ff191660021781556008018490555184907f6b437d58f4403cecb2353bf3e8f2384a91e7518f0a2b0e6762b0425b5e6c462190620028b790869062004276565b60405180910390a250505050565b600081620028d5576000620028d8565b60015b9050620028e68382620030ec565b505050565b6000858152600b602052604081205460ff1660048111156200290957fe5b14620029295760405162461bcd60e51b815260040162000732906200408f565b600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018690556000868152600b60209081526040909120805460ff19168317815586516200298a939190910191870190620036cd565b506000858152600b60209081526040909120600681018590558251620029b992600790920191840190620036cd565b506000620029de33620029cc8562003215565b620029d6620032be565b600162003328565b6000878152600b6020908152604090912060048101839055855192935062002a0f92600590910191860190620036cd565b50857fb4838dfe8d568d0b67fdac2db628f206c6ee584b385d7567e743755db005d00285838660405162002a46939291906200436f565b60405180910390a2857f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a6319828560405162002a8292919062004335565b60405180910390a2505050505050565b60008262002aa357506000620015cd565b8282028284828162002ab157fe5b041462002abd57600080fd5b9392505050565b60008082848162002ad157fe5b04949350505050565b60008282111562002aea57600080fd5b50900390565b60016000848152600b602052604090205460ff16600481111562002b1057fe5b1462002b305760405162461bcd60e51b81526004016200073290620040e1565b600062002b4b3362002b428562003215565b84600162003328565b6000858152600b6020908152604082206002810180546001818101835591855283852001859055600390910180549182018155835291819020865193945062002b9b9392019190860190620036cd565b50837f9405d6c61d91e2fc742b083fb4795fd71e261986aad67f433418e0e4be8a63198285604051620028b792919062004335565b6000818152600b602052604090206002815460ff16600481111562002bf157fe5b1462002bfc57600080fd5b600881015460001914158062002c1457600462002c17565b60035b8254839060ff1916600183600481111562002c2e57fe5b0217905550827f8b6ba55ee795a338c4c907ef43b3a72613c96c34ae6fce3131933cbf59ed4b638260405162002c65919062003f91565b60405180910390a2505050565b6000828152600b6020526040808220815161012081019092528054829060ff16600481111562002c9e57fe5b600481111562002caa57fe5b8152602001600182018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562002d4b5780601f1062002d1f5761010080835404028352916020019162002d4b565b820191906000526020600020905b81548152906001019060200180831162002d2d57829003601f168201915b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562002da557602002820191906000526020600020905b81548152602001906001019080831162002d90575b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101562002e845760008481526020908190208301805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801562002e6f5780601f1062002e435761010080835404028352916020019162002e6f565b820191906000526020600020905b81548152906001019060200180831162002e5157829003601f168201915b50505050508152602001906001019062002dd3565b50505090825250600482015460208083019190915260058301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002f255780601f1062002ef95761010080835404028352916020019162002f25565b820191906000526020600020905b81548152906001019060200180831162002f0757829003601f168201915b5050509183525050600682015460208083019190915260078301805460408051601f6002600019610100600187161502019094169390930492830185900485028101850182528281529401939283018282801562002fc75780601f1062002f9b5761010080835404028352916020019162002fc7565b820191906000526020600020905b81548152906001019060200180831162002fa957829003601f168201915b505050918352505060089190910154602090910152905060028151600481111562002fee57fe5b146200300e5760405162461bcd60e51b81526004016200073290620040b5565b6000816040015183815181106200302157fe5b6020026020010151905060008261010001518414905062000a9f8282620028c5565b60008282018381101562002abd57600080fd5b620030606200365f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600081620030dc576000620030df565b60015b9050620028e68360800151825b6000600a8381548110620030fc57fe5b90600052602060002090600b0201905060008160010183815481106200311e57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b1580156200319d57600080fd5b505afa158015620031b2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620031dc919081019062003a1f565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f8583868460405162000a6994939291906200427f565b6040805160028082526060828101909352816020015b60608152602001906001900390816200322b5790505090508160405160200162003256919062003f11565b604051602081830303815290604052816000815181106200327357fe5b60200260200101819052508160405160200162003291919062003ee1565b60405160208183030381529060405281600181518110620032ae57fe5b6020026020010181905250919050565b6040805160028082526060808301845292602083019080368337019050509050670de0b6b3a764000081600181518110620032f557fe5b6020026020010181815250506802a802f8630a240000816000815181106200331957fe5b60200260200101818152505090565b600a80546040805161016081019091526001600160a01b0387168152909190602081016200335787306200351d565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033f79392850192919091019062003762565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003479916009840191602090910190620037ba565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620034cc9083908790879062004306565b60405180910390a1811562003515577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200350c919062004276565b60405180910390a15b949350505050565b815160609060008167ffffffffffffffff811180156200353c57600080fd5b5060405190808252806020026020018201604052801562003567578160200160208202803683370190505b50905060005b8281101562003609578581815181106200358357fe5b60200260200101518682815181106200359857fe5b602002602001015186604051620035af90620037f7565b620035bd9392919062004020565b604051809103906000f080158015620035da573d6000803e3d6000fd5b50828281518110620035e857fe5b6001600160a01b03909216602092830291909101909101526001016200356d565b50949350505050565b604080516101208101909152806000815260200160608152602001606081526020016060815260200160008152602001606081526020016000815260200160608152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054600181600116156101000203166002900490600052602060002090601f01602090048101928262003705576000855562003750565b82601f106200372057805160ff191683800117855562003750565b8280016001018555821562003750579182015b828111156200375057825182559160200191906001019062003733565b506200375e92915062003805565b5090565b82805482825590600052602060002090810192821562003750579160200282015b828111156200375057825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003783565b8280548282559060005260206000209081019282156200375057916020028201828111156200375057825182559160200191906001019062003733565b6111f3806200443683390190565b5b808211156200375e576000815560010162003806565b80356001600160a01b038116811462000f6957600080fd5b600082601f83011262003845578081fd5b813560206200385e6200385883620043b5565b62004390565b82815281810190858301855b85811015620038975762003884898684358b0101620038a4565b845292840192908401906001016200386a565b5090979650505050505050565b600082601f830112620038b5578081fd5b81356020620038c86200385883620043b5565b8281528181019085830183850287018401881015620038e5578586fd5b855b858110156200389757813584529284019290840190600101620038e7565b600082601f83011262003916578081fd5b8135620039276200385882620043d4565b8181528460208386010111156200393c578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003968578081fd5b62002abd826200381c565b6000806040838503121562003986578081fd5b62003991836200381c565b91506020830135620039a38162004426565b809150509250929050565b60008060408385031215620039c1578182fd5b823567ffffffffffffffff811115620039d8578283fd5b620039e685828601620038a4565b925050620039f7602084016200381c565b90509250929050565b60006020828403121562003a12578081fd5b815162002abd8162004426565b60006020828403121562003a31578081fd5b815167ffffffffffffffff81111562003a48578182fd5b8201601f8101841362003a59578182fd5b805162003a6a6200385882620043d4565b81815285602083850101111562003a7f578384fd5b62003a92826020830160208601620043f7565b95945050505050565b60006020828403121562003aad578081fd5b5035919050565b60006020828403121562003ac6578081fd5b5051919050565b6000806040838503121562003ae0578182fd5b82359150620039f7602084016200381c565b60008060006060848603121562003b07578081fd5b8335925060208085013567ffffffffffffffff8082111562003b27578384fd5b818701915087601f83011262003b3b578384fd5b813562003b4c6200385882620043b5565b81815284810190848601875b8481101562003b855762003b728d8984358a010162003905565b8452928701929087019060010162003b58565b50909750505050604087013592508083111562003ba0578384fd5b505062003bb08682870162003834565b9150509250925092565b6000806040838503121562003bcd578182fd5b82359150602083013567ffffffffffffffff81111562003beb578182fd5b62003bf985828601620038a4565b9150509250929050565b600080600080600060a0868803121562003c1b578283fd5b85359450602086013567ffffffffffffffff8082111562003c3a578485fd5b62003c4889838a0162003905565b9550604088013591508082111562003c5e578485fd5b62003c6c89838a0162003905565b945060608801359350608088013591508082111562003c89578283fd5b5062003c988882890162003905565b9150509295509295909350565b6000806040838503121562003cb8578182fd5b50508035926020909101359150565b60008060006060848603121562003cdc578081fd5b833592506020840135915062003cf5604085016200381c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d455781516001600160a01b03168752958201959082019060010162003d1e565b509495945050505050565b6000815180845260208085018081965082840281019150828601855b8581101562003d9a57828403895262003d8784835162003ded565b9885019893509084019060010162003d6c565b5091979650505050505050565b6000815180845260208085019450808401835b8381101562003d455781518752958201959082019060010162003dba565b15159052565b6005811062003de957fe5b9052565b6000815180845262003e07816020860160208601620043f7565b601f01601f19169290920160200192915050565b600061012062003e2d84845162003dde565b602083015181602086015262003e468286018262003ded565b9150506040830151848203604086015262003e62828262003da7565b9150506060830151848203606086015262003e7e828262003d50565b9150506080830151608085015260a083015184820360a086015262003ea4828262003ded565b91505060c083015160c085015260e083015184820360e086015262003eca828262003ded565b610100948501519590940194909452509092915050565b60006502ca2a99016960d51b8252825162003f04816006850160208701620043f7565b9190910160060192915050565b600064027279016960dd1b8252825162003f33816005850160208701620043f7565b9190910160050192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600062003faa828a62003dde565b60e0602083015262003fc060e083018962003ded565b876040840152828103606084015262003fda818862003ded565b905085608084015282810360a084015262003ff6818662003ded565b9150508260c083015298975050505050505050565b60006020825262002abd602083018462003ded565b60006060825262004035606083018662003ded565b828103602084015262004049818662003ded565b91505060018060a01b0383166040830152949350505050565b60208082526013908201527219dc9bdd5c081b9bdd0814d8da19591d5b1959606a1b604082015260600190565b6020808252600c908201526b67726f75702065786973747360a01b604082015260600190565b6020808252601290820152716d7573742062652066696e616c697a696e6760701b604082015260600190565b60208082526017908201527f67726f7570206d757374206265205363686564756c6564000000000000000000604082015260600190565b6020808252600f908201526e6d61726b657420696e61637469766560881b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262002abd602083018462003e1b565b60006040825262004196604083018562003e1b565b90508260208301529392505050565b600060208252620041bb60208301845162003cfe565b6020830151610160806040850152620041d961018085018362003d0b565b91506040850151620041ef606086018262003cfe565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262004255848362003da7565b9350808701519150506200426c8286018262003dd8565b5090949350505050565b90815260200190565b600085825260018060a01b038516602083015283604083015260806060830152620042ae608083018462003ded565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e06060830152620042e760e083018762003ded565b60808301959095525060a081019290925260c090910152949350505050565b60008482526060602083015262004321606083018562003d50565b8281036040840152620042ae818562003da7565b60008382526040602083015262003515604083018462003ded565b92835260208301919091526001600160a01b0316604082015260600190565b60008482528360208301526060604083015262003a92606083018462003ded565b60405181810167ffffffffffffffff81118282101715620043ad57fe5b604052919050565b600067ffffffffffffffff821115620043ca57fe5b5060209081020190565b600067ffffffffffffffff821115620043e957fe5b50601f01601f191660200190565b60005b8381101562004414578181015183820152602001620043fa565b83811115620014855750506000910152565b80151581146200074857600080fdfe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220c3947cfe91c803dfb4c46fbb35412f3e9f7e7d04150213810330f28c9192c19f64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { @@ -1417,8 +1417,8 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(OwnedERC20)25830)dyn_storage": { - "base": "t_contract(OwnedERC20)25830", + "t_array(t_contract(OwnedERC20)25781)dyn_storage": { + "base": "t_contract(OwnedERC20)25781", "encoding": "dynamic_array", "label": "contract OwnedERC20[]", "numberOfBytes": "32" @@ -1456,7 +1456,7 @@ "label": "contract IERC20Full", "numberOfBytes": "20" }, - "t_contract(OwnedERC20)25830": { + "t_contract(OwnedERC20)25781": { "encoding": "inplace", "label": "contract OwnedERC20", "numberOfBytes": "20" @@ -1503,7 +1503,7 @@ "label": "shareTokens", "offset": 0, "slot": "1", - "type": "t_array(t_contract(OwnedERC20)25830)dyn_storage" + "type": "t_array(t_contract(OwnedERC20)25781)dyn_storage" }, { "astId": 15185, @@ -1511,7 +1511,7 @@ "label": "winner", "offset": 0, "slot": "2", - "type": "t_contract(OwnedERC20)25830" + "type": "t_contract(OwnedERC20)25781" }, { "astId": 15187, diff --git a/packages/smart/deployments/maticMumbai/MLBMarketFactoryV3.json b/packages/smart/deployments/maticMumbai/MLBMarketFactoryV3.json index e1097bd8c..81f5202f8 100644 --- a/packages/smart/deployments/maticMumbai/MLBMarketFactoryV3.json +++ b/packages/smart/deployments/maticMumbai/MLBMarketFactoryV3.json @@ -1,5 +1,5 @@ { - "address": "0x930fdaC8CBeC4279401a2bf864eeeaa85c00123D", + "address": "0xaa7156a7B4d9590220D59e219B900FfDa52F6153", "abi": [ { "inputs": [ @@ -1204,35 +1204,35 @@ "type": "function" } ], - "transactionHash": "0x3dee30b5ffa50365ad6725b2ae557ca01e36622bd65c7651fef6cc4af58842d7", + "transactionHash": "0xd8d87e3d73573804386ad8ac0fee67a1309b3d4de5ffd1e13d753ee80e716545", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0x930fdaC8CBeC4279401a2bf864eeeaa85c00123D", - "transactionIndex": 1, - "gasUsed": "4769501", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000418020000000000000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000040000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x29759bb0ec0c1aa7034e220104c463c433a31153277d01aeb2bfbca1eb95addd", - "transactionHash": "0x3dee30b5ffa50365ad6725b2ae557ca01e36622bd65c7651fef6cc4af58842d7", + "contractAddress": "0xaa7156a7B4d9590220D59e219B900FfDa52F6153", + "transactionIndex": 0, + "gasUsed": "4769489", + "logsBloom": "0x00000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000200000000080100000000200000000000000000000010000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", + "blockHash": "0x3e9382c979753f13791feb7c0345580834104d9c7d0f9644550209db374386a2", + "transactionHash": "0xd8d87e3d73573804386ad8ac0fee67a1309b3d4de5ffd1e13d753ee80e716545", "logs": [ { - "transactionIndex": 1, - "blockNumber": 19809866, - "transactionHash": "0x3dee30b5ffa50365ad6725b2ae557ca01e36622bd65c7651fef6cc4af58842d7", + "transactionIndex": 0, + "blockNumber": 20388714, + "transactionHash": "0xd8d87e3d73573804386ad8ac0fee67a1309b3d4de5ffd1e13d753ee80e716545", "address": "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x000000000000000000000000930fdac8cbec4279401a2bf864eeeaa85c00123d", + "0x000000000000000000000000aa7156a7b4d9590220d59e219b900ffda52f6153", "0x00000000000000000000000059ddfe9961e050bda1ed9bf9ccd009948036dd76" ], "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "logIndex": 2, - "blockHash": "0x29759bb0ec0c1aa7034e220104c463c433a31153277d01aeb2bfbca1eb95addd" + "logIndex": 0, + "blockHash": "0x3e9382c979753f13791feb7c0345580834104d9c7d0f9644550209db374386a2" }, { - "transactionIndex": 1, - "blockNumber": 19809866, - "transactionHash": "0x3dee30b5ffa50365ad6725b2ae557ca01e36622bd65c7651fef6cc4af58842d7", + "transactionIndex": 0, + "blockNumber": 20388714, + "transactionHash": "0xd8d87e3d73573804386ad8ac0fee67a1309b3d4de5ffd1e13d753ee80e716545", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -1240,13 +1240,13 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x0000000000000000000000000000000000000000000000000032d581f695260000000000000000000000000000000000000000000000000364a11ac1373a2e290000000000000000000000000000000000000000000000000215a75a90804400000000000000000000000000000000000000000000000003646e453f40a5082900000000000000000000000000000000000000000000000002487cdc87156a00", - "logIndex": 3, - "blockHash": "0x29759bb0ec0c1aa7034e220104c463c433a31153277d01aeb2bfbca1eb95addd" + "data": "0x0000000000000000000000000000000000000000000000000032d57994d0be0000000000000000000000000000000000000000000000000335406e042182ce7400000000000000000000000000000000000000000000000002ab5d43cbb53af0000000000000000000000000000000000000000000000003350d988a8cb2107400000000000000000000000000000000000000000000000002de32bd6085f8f0", + "logIndex": 1, + "blockHash": "0x3e9382c979753f13791feb7c0345580834104d9c7d0f9644550209db374386a2" } ], - "blockNumber": 19809866, - "cumulativeGasUsed": "4790501", + "blockNumber": 20388714, + "cumulativeGasUsed": "4769489", "status": 1, "byzantium": true }, @@ -1263,10 +1263,10 @@ "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1" ], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/MLBMarketFactoryV3.sol\":\"MLBMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/MLBMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MLBMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasHeadToHeadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.4.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0xd632c5a75f27225b1bd4aec9e0b8610937e619751adb51cb03812c9f9badc886\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405260006007553480156200001657600080fd5b50604051620056403803806200564083398101604081905262000039916200050c565b604080518082018252600680825265076312e342e360d41b60208084019190915283518085018552600a815269139bc810dbdb9d195cdd60b21b81830152600080546001600160a01b038e81166001600160a01b031992831633178316178355600180548f8316908416811790915560098e9055600280548e84169085161790558b51600355948b015160049081558b8901516005558654909216908a1617909455945163095ea7b360e01b815293948694909391928d928d928d928d928d928d929163095ea7b39162000114918791600019910162000628565b602060405180830381600087803b1580156200012f57600080fd5b505af115801562000144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016a9190620005ff565b50600a62000177620002d5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001ce939285019291909101906200034b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162000250916009840191602090910190620003b5565b506101409190910151600a909101805460ff1916911515919091179055505050600e859055505081516200028d9150600f906020840190620003f3565b5050601080546001600160a01b0319166001600160a01b039390931692909217909155508051620002c6906011906020840190620003f3565b5050505050505050506200065a565b620002df62000475565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b828054828255906000526020600020908101928215620003a3579160200282015b82811115620003a357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036c565b50620003b1929150620004e3565b5090565b828054828255906000526020600020908101928215620003a3579160200282015b82811115620003a3578251825591602001919060010190620003d6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200042b5760008555620003a3565b82601f106200044657805160ff1916838001178555620003a3565b82800160010185558215620003a35791820182811115620003a3578251825591602001919060010190620003d6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003b15760008155600101620004e4565b8051620005078162000641565b919050565b6000806000806000806000610120888a03121562000528578283fd5b8751620005358162000641565b809750506020808901516200054a8162000641565b60408a015160608b01519198509650620005648162000641565b9450609f89018a1362000575578384fd5b604051606081016001600160401b03811182821017156200059257fe5b6040528060808b0160e08c018d811115620005ab578788fd5b875b6003811015620005cc57825184529285019291850191600101620005ad565b50839750620005db81620004fa565b96505050505050620005f16101008901620004fa565b905092959891949750929550565b60006020828403121562000611578081fd5b8151801515811462000621578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200065757600080fd5b50565b614fd6806200066a6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039d6565b60405180910390f35b620002be620002b836600462003744565b6200068e565b005b620002be620002d1366004620033fe565b620009bb565b620002ee620002e836600462003744565b62000a09565b6040516200029e919062003b88565b620002ee6200030e36600462003592565b62000e42565b620002ee6200032536600462003592565b62000e69565b620002ee6200033c366004620033e1565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e919062003951565b620002ee62001058565b620003796200105e565b6040516200029e919062003900565b6200039f6200039936600462003592565b6200106d565b6040516200029e919062003966565b620003c5620003bf36600462003592565b620011f7565b6040516200029e919062003b4f565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003592565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033e1565b620014b6565b620002be6200044536600462003592565b62001572565b620002ee6200045c366004620035c4565b6200158f565b620003566200047336600462003646565b620019b1565b620002ee6200048a36600462003592565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003592565b62001a1f565b6040516200029e98979695949392919062003971565b620002ee620004e236600462003592565b62001b85565b62000356620004f936600462003592565b62001b8c565b6200037962001c36565b620002be6200051a36600462003592565b62001c45565b6200037962001c62565b620002be6200053b366004620033e1565b62001c71565b620002ee6200055236600462003439565b62001cdd565b6200056f6200056936600462003592565b62001d2b565b6040516200029e919062003a7e565b620002ee62001eca565b620002be62000599366004620035f2565b62001ed0565b6200039f620005b0366004620033e1565b62002444565b620005cd620005c736600462003592565b620024ae565b6040516200029e92919062003b64565b620002ee620005ee36600462003592565b620024e7565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003914565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034f7565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003938565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003d05565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003938565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250990919063ffffffff16565b906200253b565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250990919063ffffffff16565b905062000cdc8162000cd5858562002551565b9062002551565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003938565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034f7565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b88565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034f7565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003d05565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003938565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034f7565b505b905090565b6060600062000f8f62002567565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b6565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003161565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003938565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034f7565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a53565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177190339060040162003900565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035ab565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250990919063ffffffff16565b905062001821828262002551565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003938565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034f7565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f919081019062003516565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bc0565b60405180910390a25091979650505050505050565b6010546060906001600160a01b03163314620019cc57600080fd5b620019d982888762002622565b9050620019f68882620019eb62002672565b868a898d8c62002697565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c8957600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d235762001d1862001d1086838151811062001d0157fe5b6020026020010151866200158f565b839062002859565b915060010162001ce2565b509392505050565b62001d35620031b5565b600a54821062001d515762001d496200286c565b905062000e64565b600a828154811062001d5f57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc4575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001ea857602002820191906000526020600020905b81548152602001906001019080831162001e93575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b6010546001600160a01b0316331462001ee857600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0957fe5b1462001f1457600080fd5b600286600481111562001f2357fe5b60ff16101562001f3257600080fd5b60408051610140810190915281546200219891908390829060ff16600481111562001f5957fe5b600481111562001f6557fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fba57602002820191906000526020600020905b81548152602001906001019080831162001fa5575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201457602002820191906000526020600020905b81548152602001906001019080831162001fff575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020d85780601f10620020ac57610100808354040283529160200191620020d8565b820191906000526020600020905b815481529060010190602001808311620020ba57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021705780601f10620021445761010080835404028352916020019162002170565b820191906000526020600020905b8154815290600101906020018083116200215257829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028e2565b15620021af57620021a9876200293a565b62002412565b60408051610140810190915281546200241291908390829060ff166004811115620021d657fe5b6004811115620021e257fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223757602002820191906000526020600020905b81548152602001906001019080831162002222575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229157602002820191906000526020600020905b8154815260200190600101908083116200227c575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023555780601f10620023295761010080835404028352916020019162002355565b820191906000526020600020905b8154815290600101906020018083116200233757829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ed5780601f10620023c157610100808354040283529160200191620023ed565b820191906000526020600020905b815481529060010190602001808311620023cf57829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029f0565b80548690829060ff191660018360048111156200242b57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245d57600080fd5b6001600160a01b0382166200247157600080fd5b60005462002489906001600160a01b03168362002a16565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b862003161565b6000600c8381548110620024c857fe5b90600052602060002001549050620024e081620011f7565b9150915091565b600c8181548110620024f857600080fd5b600091825260209091200154905081565b6000826200251a575060006200156c565b828202828482816200252857fe5b04146200253457600080fd5b9392505050565b6000808284816200254857fe5b04949350505050565b6000828211156200256157600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258757fe5b906000526020600020015490506200259f81620025b6565b15620025ac576001909201915b506001016200256c565b600080620025c48362001b8c565b90506000805b825181101562001d23576000838281518110620025e357fe5b602002602001015190508060001415801562002607575062002605816200106d565b155b156200261857600192505062001d23565b50600101620025ca565b604080516001808252818301909252606091602080830190803683370190505090506200265184848462002a1a565b816000815181106200265f57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b557fe5b14620026d55760405162461bcd60e51b8152600401620015bb9062003a2d565b60005b8751811015620027185788600d60008a8481518110620026f457fe5b602090810291909101810151825281019190915260400160002055600101620026d8565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff19168317815589516200277a9391909101918a019062003223565b506000888152600b602090815260409091208751620027a29260029092019189019062003223565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027df9260069092019185019062003273565b506000888152600b602090815260409091208251620028079260079092019184019062003273565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284798979695949392919062003c85565b60405180910390a15050505050505050565b6000828201838110156200253457600080fd5b62002876620031b5565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620028f857fe5b60808a015160a08b0151929091141592508714159086141583806200291a5750825b80620029235750815b806200292c5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200299557602002820191906000526020600020905b81548152602001906001019080831162002980575b5050505050905060005b8151811015620029eb576000828281518110620029b857fe5b602002602001015190508060001415620029d35750620029e2565b620029e081600062002ae2565b505b6001016200299f565b505050565b620029eb836020015160008151811062002a0657fe5b6020026020010151838362002c0b565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ada939192909183018282801562002aae5780601f1062002a825761010080835404028352916020019162002aae565b820191906000526020600020905b81548152906001019060200180831162002a9057829003601f168201915b5050505050848462002ad48860016002811062002ac757fe5b6020020151895162002c2d565b62002d37565b949350505050565b6000600a838154811062002af257fe5b90600052602060002090600b02019050600081600101838154811062002b1457fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b9357600080fd5b505afa15801562002ba8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bd2919081019062003516565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b91565b600062002c19838362002d62565b905062002c27848262002ae2565b50505050565b6060600062002c3c8462002d91565b9050600062002c4b8462002d91565b905081810162002c6a8162000c916802a802f8630a2400008662002509565b925062002c868162000c916802a802f8630a2400008562002509565b9150670de0b6b3a764000083101562002c9e57600080fd5b670de0b6b3a764000082101562002cb457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002cec57fe5b602002602001018181525050828460018151811062002d0757fe5b602002602001018181525050818460028151811062002d2257fe5b60200260200101818152505050505092915050565b60008062002d4786868662002df3565b905062002d58338285600162002e78565b9695505050505050565b60008183111562002d76575060026200156c565b8183101562002d88575060016200156c565b5060006200156c565b60008082121562002dd057600082900362002dc762002db282606462002859565b62000c91836802a802f8630a24000062002509565b91505062000e64565b62001d4962002de183606462002859565b690109a12906aff6100000906200253b565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e0b579050509050838160008151811062002e3257fe5b6020026020010181905250818160018151811062002e4c57fe5b6020026020010181905250828160028151811062002e6657fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002ea787306200306c565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f4793928501929190910190620032f5565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fc991600984019160209091019062003223565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200301c9083908790879062003c0e565b60405180910390a1811562002ada577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200305c919062003b88565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308b57600080fd5b50604051908082528060200260200182016040528015620030b6578160200160208202803683370190505b50905060005b828110156200315857858181518110620030d257fe5b6020026020010151868281518110620030e757fe5b602002602001015186604051620030fe906200334d565b6200310c93929190620039eb565b604051809103906000f08015801562003129573d6000803e3d6000fd5b508282815181106200313757fe5b6001600160a01b0390921660209283029190910190910152600101620030bc565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182559160200191906001019062003244565b506200326f9291506200335b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ab576000855562003261565b82601f10620032c657805160ff191683800117855562003261565b828001600101855582156200326157918201828111156200326157825182559160200191906001019062003244565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003316565b6111f38062003dae83390190565b5b808211156200326f57600081556001016200335c565b80356001600160a01b038116811462000e6457600080fd5b600082601f8301126200339b578081fd5b8135620033b2620033ac8262003d49565b62003d24565b818152846020838601011115620033c7578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033f3578081fd5b620025348262003372565b6000806040838503121562003411578081fd5b6200341c8362003372565b915060208301356200342e8162003d9b565b809150509250929050565b600080604083850312156200344c578182fd5b823567ffffffffffffffff8082111562003464578384fd5b818501915085601f83011262003478578384fd5b81356020828211156200348757fe5b80820292506200349981840162003d24565b8281528181019085830185870184018b1015620034b4578889fd5b8896505b84871015620034d8578035835260019690960195918301918301620034b8565b509650620034ea905087820162003372565b9450505050509250929050565b60006020828403121562003509578081fd5b8151620025348162003d9b565b60006020828403121562003528578081fd5b815167ffffffffffffffff8111156200353f578182fd5b8201601f8101841362003550578182fd5b805162003561620033ac8262003d49565b81815285602083850101111562003576578384fd5b6200358982602083016020860162003d6c565b95945050505050565b600060208284031215620035a4578081fd5b5035919050565b600060208284031215620035bd578081fd5b5051919050565b60008060408385031215620035d7578182fd5b82359150620035e96020840162003372565b90509250929050565b60008060008060008060c087890312156200360b578182fd5b8635955060208701356005811062003621578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600061010080898b03121562003663578586fd5b883597506020808a013567ffffffffffffffff8082111562003683578889fd5b620036918d838e016200338a565b995060408c0135985060608c0135915080821115620036ae578485fd5b620036bc8d838e016200338a565b975060808c0135965060a08c013595508c60df8d0112620036db578485fd5b6040519150604082018281108282111715620036f357fe5b604052508060c08c01848d018e10156200370b578586fd5b8594505b6002851015620037305780358252600194909401939083019083016200370f565b505080935050505092959891949750929550565b60008060006060848603121562003759578081fd5b8335925060208401359150620037726040850162003372565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037c25781516001600160a01b0316875295820195908201906001016200379b565b509495945050505050565b6000815180845260208085019450808401835b83811015620037c257815187529582019590820190600101620037e0565b15159052565b600581106200380f57fe5b9052565b600081518084526200382d81602086016020860162003d6c565b601f01601f19169290920160200192915050565b60006101406200385384845162003804565b60208301518160208601526200386c82860182620037cd565b91505060408301518482036040860152620038888282620037cd565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038c2828262003813565b91505060e083015184820360e0860152620038de828262003813565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025346020830184620037cd565b901515815260200190565b600061010062003982838c62003804565b896020840152886040840152876060840152806080840152620039a88184018862003813565b905082810360a0840152620039be818762003813565b60c0840195909552505060e001529695505050505050565b60006020825262002534602083018462003813565b60006060825262003a00606083018662003813565b828103602084015262003a14818662003813565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a946020830184516200377b565b602083015161016080604085015262003ab261018085018362003788565b9150604085015162003ac860608601826200377b565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b2e8483620037cd565b93508087015191505062003b4582860182620037fe565b5090949350505050565b60006020825262002534602083018462003841565b60006040825262003b79604083018562003841565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d58608083018462003813565b600088825260018060a01b038816602083015286604083015260e0606083015262003bef60e083018762003813565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c6c57607f1988870301845262003c5986835162003813565b9550928401929084019060010162003c3a565b5050505050828103604084015262002d588185620037cd565b60006101008a835280602084015262003ca18184018b620037cd565b9050828103604084015262003cb7818a620037cd565b905087606084015286608084015282810360a084015262003cd9818762003813565b905082810360c084015262003cef818662003813565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d4157fe5b604052919050565b600067ffffffffffffffff82111562003d5e57fe5b50601f01601f191660200190565b60005b8381101562003d8957818101518382015260200162003d6f565b8381111562002c275750506000910152565b801515811462003daa57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220ceb6ccef029deda8e993443a7ba71883f1b5dcf3d47b98bb578f21494240f13964736f6c63430007060033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039d6565b60405180910390f35b620002be620002b836600462003744565b6200068e565b005b620002be620002d1366004620033fe565b620009bb565b620002ee620002e836600462003744565b62000a09565b6040516200029e919062003b88565b620002ee6200030e36600462003592565b62000e42565b620002ee6200032536600462003592565b62000e69565b620002ee6200033c366004620033e1565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e919062003951565b620002ee62001058565b620003796200105e565b6040516200029e919062003900565b6200039f6200039936600462003592565b6200106d565b6040516200029e919062003966565b620003c5620003bf36600462003592565b620011f7565b6040516200029e919062003b4f565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003592565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033e1565b620014b6565b620002be6200044536600462003592565b62001572565b620002ee6200045c366004620035c4565b6200158f565b620003566200047336600462003646565b620019b1565b620002ee6200048a36600462003592565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003592565b62001a1f565b6040516200029e98979695949392919062003971565b620002ee620004e236600462003592565b62001b85565b62000356620004f936600462003592565b62001b8c565b6200037962001c36565b620002be6200051a36600462003592565b62001c45565b6200037962001c62565b620002be6200053b366004620033e1565b62001c71565b620002ee6200055236600462003439565b62001cdd565b6200056f6200056936600462003592565b62001d2b565b6040516200029e919062003a7e565b620002ee62001eca565b620002be62000599366004620035f2565b62001ed0565b6200039f620005b0366004620033e1565b62002444565b620005cd620005c736600462003592565b620024ae565b6040516200029e92919062003b64565b620002ee620005ee36600462003592565b620024e7565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003914565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034f7565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003938565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003d05565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003938565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250990919063ffffffff16565b906200253b565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250990919063ffffffff16565b905062000cdc8162000cd5858562002551565b9062002551565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003938565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034f7565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b88565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034f7565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003d05565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003938565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034f7565b505b905090565b6060600062000f8f62002567565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b6565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003161565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003938565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034f7565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a53565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177190339060040162003900565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035ab565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250990919063ffffffff16565b905062001821828262002551565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003938565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034f7565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f919081019062003516565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bc0565b60405180910390a25091979650505050505050565b6010546060906001600160a01b03163314620019cc57600080fd5b620019d982888762002622565b9050620019f68882620019eb62002672565b868a898d8c62002697565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c8957600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d235762001d1862001d1086838151811062001d0157fe5b6020026020010151866200158f565b839062002859565b915060010162001ce2565b509392505050565b62001d35620031b5565b600a54821062001d515762001d496200286c565b905062000e64565b600a828154811062001d5f57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc4575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001ea857602002820191906000526020600020905b81548152602001906001019080831162001e93575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b6010546001600160a01b0316331462001ee857600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0957fe5b1462001f1457600080fd5b600286600481111562001f2357fe5b60ff16101562001f3257600080fd5b60408051610140810190915281546200219891908390829060ff16600481111562001f5957fe5b600481111562001f6557fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fba57602002820191906000526020600020905b81548152602001906001019080831162001fa5575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201457602002820191906000526020600020905b81548152602001906001019080831162001fff575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020d85780601f10620020ac57610100808354040283529160200191620020d8565b820191906000526020600020905b815481529060010190602001808311620020ba57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021705780601f10620021445761010080835404028352916020019162002170565b820191906000526020600020905b8154815290600101906020018083116200215257829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028e2565b15620021af57620021a9876200293a565b62002412565b60408051610140810190915281546200241291908390829060ff166004811115620021d657fe5b6004811115620021e257fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223757602002820191906000526020600020905b81548152602001906001019080831162002222575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229157602002820191906000526020600020905b8154815260200190600101908083116200227c575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023555780601f10620023295761010080835404028352916020019162002355565b820191906000526020600020905b8154815290600101906020018083116200233757829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ed5780601f10620023c157610100808354040283529160200191620023ed565b820191906000526020600020905b815481529060010190602001808311620023cf57829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029f0565b80548690829060ff191660018360048111156200242b57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245d57600080fd5b6001600160a01b0382166200247157600080fd5b60005462002489906001600160a01b03168362002a16565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b862003161565b6000600c8381548110620024c857fe5b90600052602060002001549050620024e081620011f7565b9150915091565b600c8181548110620024f857600080fd5b600091825260209091200154905081565b6000826200251a575060006200156c565b828202828482816200252857fe5b04146200253457600080fd5b9392505050565b6000808284816200254857fe5b04949350505050565b6000828211156200256157600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258757fe5b906000526020600020015490506200259f81620025b6565b15620025ac576001909201915b506001016200256c565b600080620025c48362001b8c565b90506000805b825181101562001d23576000838281518110620025e357fe5b602002602001015190508060001415801562002607575062002605816200106d565b155b156200261857600192505062001d23565b50600101620025ca565b604080516001808252818301909252606091602080830190803683370190505090506200265184848462002a1a565b816000815181106200265f57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b557fe5b14620026d55760405162461bcd60e51b8152600401620015bb9062003a2d565b60005b8751811015620027185788600d60008a8481518110620026f457fe5b602090810291909101810151825281019190915260400160002055600101620026d8565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff19168317815589516200277a9391909101918a019062003223565b506000888152600b602090815260409091208751620027a29260029092019189019062003223565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027df9260069092019185019062003273565b506000888152600b602090815260409091208251620028079260079092019184019062003273565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284798979695949392919062003c85565b60405180910390a15050505050505050565b6000828201838110156200253457600080fd5b62002876620031b5565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620028f857fe5b60808a015160a08b0151929091141592508714159086141583806200291a5750825b80620029235750815b806200292c5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200299557602002820191906000526020600020905b81548152602001906001019080831162002980575b5050505050905060005b8151811015620029eb576000828281518110620029b857fe5b602002602001015190508060001415620029d35750620029e2565b620029e081600062002ae2565b505b6001016200299f565b505050565b620029eb836020015160008151811062002a0657fe5b6020026020010151838362002c0b565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ada939192909183018282801562002aae5780601f1062002a825761010080835404028352916020019162002aae565b820191906000526020600020905b81548152906001019060200180831162002a9057829003601f168201915b5050505050848462002ad48860016002811062002ac757fe5b6020020151895162002c2d565b62002d37565b949350505050565b6000600a838154811062002af257fe5b90600052602060002090600b02019050600081600101838154811062002b1457fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b9357600080fd5b505afa15801562002ba8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bd2919081019062003516565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b91565b600062002c19838362002d62565b905062002c27848262002ae2565b50505050565b6060600062002c3c8462002d91565b9050600062002c4b8462002d91565b905081810162002c6a8162000c916802a802f8630a2400008662002509565b925062002c868162000c916802a802f8630a2400008562002509565b9150670de0b6b3a764000083101562002c9e57600080fd5b670de0b6b3a764000082101562002cb457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002cec57fe5b602002602001018181525050828460018151811062002d0757fe5b602002602001018181525050818460028151811062002d2257fe5b60200260200101818152505050505092915050565b60008062002d4786868662002df3565b905062002d58338285600162002e78565b9695505050505050565b60008183111562002d76575060026200156c565b8183101562002d88575060016200156c565b5060006200156c565b60008082121562002dd057600082900362002dc762002db282606462002859565b62000c91836802a802f8630a24000062002509565b91505062000e64565b62001d4962002de183606462002859565b690109a12906aff6100000906200253b565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e0b579050509050838160008151811062002e3257fe5b6020026020010181905250818160018151811062002e4c57fe5b6020026020010181905250828160028151811062002e6657fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002ea787306200306c565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f4793928501929190910190620032f5565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fc991600984019160209091019062003223565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200301c9083908790879062003c0e565b60405180910390a1811562002ada577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200305c919062003b88565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308b57600080fd5b50604051908082528060200260200182016040528015620030b6578160200160208202803683370190505b50905060005b828110156200315857858181518110620030d257fe5b6020026020010151868281518110620030e757fe5b602002602001015186604051620030fe906200334d565b6200310c93929190620039eb565b604051809103906000f08015801562003129573d6000803e3d6000fd5b508282815181106200313757fe5b6001600160a01b0390921660209283029190910190910152600101620030bc565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182559160200191906001019062003244565b506200326f9291506200335b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ab576000855562003261565b82601f10620032c657805160ff191683800117855562003261565b828001600101855582156200326157918201828111156200326157825182559160200191906001019062003244565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003316565b6111f38062003dae83390190565b5b808211156200326f57600081556001016200335c565b80356001600160a01b038116811462000e6457600080fd5b600082601f8301126200339b578081fd5b8135620033b2620033ac8262003d49565b62003d24565b818152846020838601011115620033c7578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033f3578081fd5b620025348262003372565b6000806040838503121562003411578081fd5b6200341c8362003372565b915060208301356200342e8162003d9b565b809150509250929050565b600080604083850312156200344c578182fd5b823567ffffffffffffffff8082111562003464578384fd5b818501915085601f83011262003478578384fd5b81356020828211156200348757fe5b80820292506200349981840162003d24565b8281528181019085830185870184018b1015620034b4578889fd5b8896505b84871015620034d8578035835260019690960195918301918301620034b8565b509650620034ea905087820162003372565b9450505050509250929050565b60006020828403121562003509578081fd5b8151620025348162003d9b565b60006020828403121562003528578081fd5b815167ffffffffffffffff8111156200353f578182fd5b8201601f8101841362003550578182fd5b805162003561620033ac8262003d49565b81815285602083850101111562003576578384fd5b6200358982602083016020860162003d6c565b95945050505050565b600060208284031215620035a4578081fd5b5035919050565b600060208284031215620035bd578081fd5b5051919050565b60008060408385031215620035d7578182fd5b82359150620035e96020840162003372565b90509250929050565b60008060008060008060c087890312156200360b578182fd5b8635955060208701356005811062003621578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600061010080898b03121562003663578586fd5b883597506020808a013567ffffffffffffffff8082111562003683578889fd5b620036918d838e016200338a565b995060408c0135985060608c0135915080821115620036ae578485fd5b620036bc8d838e016200338a565b975060808c0135965060a08c013595508c60df8d0112620036db578485fd5b6040519150604082018281108282111715620036f357fe5b604052508060c08c01848d018e10156200370b578586fd5b8594505b6002851015620037305780358252600194909401939083019083016200370f565b505080935050505092959891949750929550565b60008060006060848603121562003759578081fd5b8335925060208401359150620037726040850162003372565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037c25781516001600160a01b0316875295820195908201906001016200379b565b509495945050505050565b6000815180845260208085019450808401835b83811015620037c257815187529582019590820190600101620037e0565b15159052565b600581106200380f57fe5b9052565b600081518084526200382d81602086016020860162003d6c565b601f01601f19169290920160200192915050565b60006101406200385384845162003804565b60208301518160208601526200386c82860182620037cd565b91505060408301518482036040860152620038888282620037cd565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038c2828262003813565b91505060e083015184820360e0860152620038de828262003813565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025346020830184620037cd565b901515815260200190565b600061010062003982838c62003804565b896020840152886040840152876060840152806080840152620039a88184018862003813565b905082810360a0840152620039be818762003813565b60c0840195909552505060e001529695505050505050565b60006020825262002534602083018462003813565b60006060825262003a00606083018662003813565b828103602084015262003a14818662003813565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a946020830184516200377b565b602083015161016080604085015262003ab261018085018362003788565b9150604085015162003ac860608601826200377b565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b2e8483620037cd565b93508087015191505062003b4582860182620037fe565b5090949350505050565b60006020825262002534602083018462003841565b60006040825262003b79604083018562003841565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d58608083018462003813565b600088825260018060a01b038816602083015286604083015260e0606083015262003bef60e083018762003813565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c6c57607f1988870301845262003c5986835162003813565b9550928401929084019060010162003c3a565b5050505050828103604084015262002d588185620037cd565b60006101008a835280602084015262003ca18184018b620037cd565b9050828103604084015262003cb7818a620037cd565b905087606084015286608084015282810360a084015262003cd9818762003813565b905082810360c084015262003cef818662003813565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d4157fe5b604052919050565b600067ffffffffffffffff82111562003d5e57fe5b50601f01601f191660200190565b60005b8381101562003d8957818101518382015260200162003d6f565b8381111562002c275750506000910152565b801515811462003daa57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220ceb6ccef029deda8e993443a7ba71883f1b5dcf3d47b98bb578f21494240f13964736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/MLBMarketFactoryV3.sol\":\"MLBMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/MLBMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MLBMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasHeadToHeadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.4.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0xd632c5a75f27225b1bd4aec9e0b8610937e619751adb51cb03812c9f9badc886\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006007553480156200001657600080fd5b50604051620056403803806200564083398101604081905262000039916200050c565b604080518082018252600680825265076312e342e360d41b60208084019190915283518085018552600a815269139bc810dbdb9d195cdd60b21b81830152600080546001600160a01b038e81166001600160a01b031992831633178316178355600180548f8316908416811790915560098e9055600280548e84169085161790558b51600355948b015160049081558b8901516005558654909216908a1617909455945163095ea7b360e01b815293948694909391928d928d928d928d928d928d929163095ea7b39162000114918791600019910162000628565b602060405180830381600087803b1580156200012f57600080fd5b505af115801562000144573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016a9190620005ff565b50600a62000177620002d5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001ce939285019291909101906200034b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162000250916009840191602090910190620003b5565b506101409190910151600a909101805460ff1916911515919091179055505050600e859055505081516200028d9150600f906020840190620003f3565b5050601080546001600160a01b0319166001600160a01b039390931692909217909155508051620002c6906011906020840190620003f3565b5050505050505050506200065a565b620002df62000475565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b828054828255906000526020600020908101928215620003a3579160200282015b82811115620003a357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036c565b50620003b1929150620004e3565b5090565b828054828255906000526020600020908101928215620003a3579160200282015b82811115620003a3578251825591602001919060010190620003d6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200042b5760008555620003a3565b82601f106200044657805160ff1916838001178555620003a3565b82800160010185558215620003a35791820182811115620003a3578251825591602001919060010190620003d6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003b15760008155600101620004e4565b8051620005078162000641565b919050565b6000806000806000806000610120888a03121562000528578283fd5b8751620005358162000641565b809750506020808901516200054a8162000641565b60408a015160608b01519198509650620005648162000641565b9450609f89018a1362000575578384fd5b604051606081016001600160401b03811182821017156200059257fe5b6040528060808b0160e08c018d811115620005ab578788fd5b875b6003811015620005cc57825184529285019291850191600101620005ad565b50839750620005db81620004fa565b96505050505050620005f16101008901620004fa565b905092959891949750929550565b60006020828403121562000611578081fd5b8151801515811462000621578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200065757600080fd5b50565b614fd6806200066a6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039d6565b60405180910390f35b620002be620002b836600462003744565b6200068e565b005b620002be620002d1366004620033fe565b620009bb565b620002ee620002e836600462003744565b62000a09565b6040516200029e919062003b88565b620002ee6200030e36600462003592565b62000e42565b620002ee6200032536600462003592565b62000e69565b620002ee6200033c366004620033e1565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e919062003951565b620002ee62001058565b620003796200105e565b6040516200029e919062003900565b6200039f6200039936600462003592565b6200106d565b6040516200029e919062003966565b620003c5620003bf36600462003592565b620011f7565b6040516200029e919062003b4f565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003592565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033e1565b620014b6565b620002be6200044536600462003592565b62001572565b620002ee6200045c366004620035c4565b6200158f565b620003566200047336600462003646565b620019b1565b620002ee6200048a36600462003592565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003592565b62001a1f565b6040516200029e98979695949392919062003971565b620002ee620004e236600462003592565b62001b85565b62000356620004f936600462003592565b62001b8c565b6200037962001c36565b620002be6200051a36600462003592565b62001c45565b6200037962001c62565b620002be6200053b366004620033e1565b62001c71565b620002ee6200055236600462003439565b62001cdd565b6200056f6200056936600462003592565b62001d2b565b6040516200029e919062003a7e565b620002ee62001eca565b620002be62000599366004620035f2565b62001ed0565b6200039f620005b0366004620033e1565b62002444565b620005cd620005c736600462003592565b620024ae565b6040516200029e92919062003b64565b620002ee620005ee36600462003592565b620024e7565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003914565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034f7565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003938565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003d05565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003938565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250990919063ffffffff16565b906200253b565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250990919063ffffffff16565b905062000cdc8162000cd5858562002551565b9062002551565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003938565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034f7565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b88565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034f7565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003d05565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003938565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034f7565b505b905090565b6060600062000f8f62002567565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b6565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003161565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003938565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034f7565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a53565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177190339060040162003900565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035ab565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250990919063ffffffff16565b905062001821828262002551565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003938565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034f7565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f919081019062003516565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bc0565b60405180910390a25091979650505050505050565b6010546060906001600160a01b03163314620019cc57600080fd5b620019d982888762002622565b9050620019f68882620019eb62002672565b868a898d8c62002697565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c8957600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d235762001d1862001d1086838151811062001d0157fe5b6020026020010151866200158f565b839062002859565b915060010162001ce2565b509392505050565b62001d35620031b5565b600a54821062001d515762001d496200286c565b905062000e64565b600a828154811062001d5f57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc4575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001ea857602002820191906000526020600020905b81548152602001906001019080831162001e93575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b6010546001600160a01b0316331462001ee857600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0957fe5b1462001f1457600080fd5b600286600481111562001f2357fe5b60ff16101562001f3257600080fd5b60408051610140810190915281546200219891908390829060ff16600481111562001f5957fe5b600481111562001f6557fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fba57602002820191906000526020600020905b81548152602001906001019080831162001fa5575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201457602002820191906000526020600020905b81548152602001906001019080831162001fff575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020d85780601f10620020ac57610100808354040283529160200191620020d8565b820191906000526020600020905b815481529060010190602001808311620020ba57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021705780601f10620021445761010080835404028352916020019162002170565b820191906000526020600020905b8154815290600101906020018083116200215257829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028e2565b15620021af57620021a9876200293a565b62002412565b60408051610140810190915281546200241291908390829060ff166004811115620021d657fe5b6004811115620021e257fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223757602002820191906000526020600020905b81548152602001906001019080831162002222575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229157602002820191906000526020600020905b8154815260200190600101908083116200227c575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023555780601f10620023295761010080835404028352916020019162002355565b820191906000526020600020905b8154815290600101906020018083116200233757829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ed5780601f10620023c157610100808354040283529160200191620023ed565b820191906000526020600020905b815481529060010190602001808311620023cf57829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029f0565b80548690829060ff191660018360048111156200242b57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245d57600080fd5b6001600160a01b0382166200247157600080fd5b60005462002489906001600160a01b03168362002a16565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b862003161565b6000600c8381548110620024c857fe5b90600052602060002001549050620024e081620011f7565b9150915091565b600c8181548110620024f857600080fd5b600091825260209091200154905081565b6000826200251a575060006200156c565b828202828482816200252857fe5b04146200253457600080fd5b9392505050565b6000808284816200254857fe5b04949350505050565b6000828211156200256157600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258757fe5b906000526020600020015490506200259f81620025b6565b15620025ac576001909201915b506001016200256c565b600080620025c48362001b8c565b90506000805b825181101562001d23576000838281518110620025e357fe5b602002602001015190508060001415801562002607575062002605816200106d565b155b156200261857600192505062001d23565b50600101620025ca565b604080516001808252818301909252606091602080830190803683370190505090506200265184848462002a1a565b816000815181106200265f57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b557fe5b14620026d55760405162461bcd60e51b8152600401620015bb9062003a2d565b60005b8751811015620027185788600d60008a8481518110620026f457fe5b602090810291909101810151825281019190915260400160002055600101620026d8565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff19168317815589516200277a9391909101918a019062003223565b506000888152600b602090815260409091208751620027a29260029092019189019062003223565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027df9260069092019185019062003273565b506000888152600b602090815260409091208251620028079260079092019184019062003273565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284798979695949392919062003c85565b60405180910390a15050505050505050565b6000828201838110156200253457600080fd5b62002876620031b5565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620028f857fe5b60808a015160a08b0151929091141592508714159086141583806200291a5750825b80620029235750815b806200292c5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200299557602002820191906000526020600020905b81548152602001906001019080831162002980575b5050505050905060005b8151811015620029eb576000828281518110620029b857fe5b602002602001015190508060001415620029d35750620029e2565b620029e081600062002ae2565b505b6001016200299f565b505050565b620029eb836020015160008151811062002a0657fe5b6020026020010151838362002c0b565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ada939192909183018282801562002aae5780601f1062002a825761010080835404028352916020019162002aae565b820191906000526020600020905b81548152906001019060200180831162002a9057829003601f168201915b5050505050848462002ad48860016002811062002ac757fe5b6020020151895162002c2d565b62002d37565b949350505050565b6000600a838154811062002af257fe5b90600052602060002090600b02019050600081600101838154811062002b1457fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b9357600080fd5b505afa15801562002ba8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bd2919081019062003516565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b91565b600062002c19838362002d62565b905062002c27848262002ae2565b50505050565b6060600062002c3c8462002d91565b9050600062002c4b8462002d91565b905081810162002c6a8162000c916802a802f8630a2400008662002509565b925062002c868162000c916802a802f8630a2400008562002509565b9150670de0b6b3a764000083101562002c9e57600080fd5b670de0b6b3a764000082101562002cb457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002cec57fe5b602002602001018181525050828460018151811062002d0757fe5b602002602001018181525050818460028151811062002d2257fe5b60200260200101818152505050505092915050565b60008062002d4786868662002df3565b905062002d58338285600162002e78565b9695505050505050565b60008183111562002d76575060026200156c565b8183101562002d88575060016200156c565b5060006200156c565b60008082121562002dd057600082900362002dc762002db282606462002859565b62000c91836802a802f8630a24000062002509565b91505062000e64565b62001d4962002de183606462002859565b690109a12906aff6100000906200253b565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e0b579050509050838160008151811062002e3257fe5b6020026020010181905250818160018151811062002e4c57fe5b6020026020010181905250828160028151811062002e6657fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002ea787306200306c565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f4793928501929190910190620032f5565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fc991600984019160209091019062003223565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200301c9083908790879062003c0e565b60405180910390a1811562002ada577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200305c919062003b88565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308b57600080fd5b50604051908082528060200260200182016040528015620030b6578160200160208202803683370190505b50905060005b828110156200315857858181518110620030d257fe5b6020026020010151868281518110620030e757fe5b602002602001015186604051620030fe906200334d565b6200310c93929190620039eb565b604051809103906000f08015801562003129573d6000803e3d6000fd5b508282815181106200313757fe5b6001600160a01b0390921660209283029190910190910152600101620030bc565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182559160200191906001019062003244565b506200326f9291506200335b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ab576000855562003261565b82601f10620032c657805160ff191683800117855562003261565b828001600101855582156200326157918201828111156200326157825182559160200191906001019062003244565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003316565b6111f38062003dae83390190565b5b808211156200326f57600081556001016200335c565b80356001600160a01b038116811462000e6457600080fd5b600082601f8301126200339b578081fd5b8135620033b2620033ac8262003d49565b62003d24565b818152846020838601011115620033c7578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033f3578081fd5b620025348262003372565b6000806040838503121562003411578081fd5b6200341c8362003372565b915060208301356200342e8162003d9b565b809150509250929050565b600080604083850312156200344c578182fd5b823567ffffffffffffffff8082111562003464578384fd5b818501915085601f83011262003478578384fd5b81356020828211156200348757fe5b80820292506200349981840162003d24565b8281528181019085830185870184018b1015620034b4578889fd5b8896505b84871015620034d8578035835260019690960195918301918301620034b8565b509650620034ea905087820162003372565b9450505050509250929050565b60006020828403121562003509578081fd5b8151620025348162003d9b565b60006020828403121562003528578081fd5b815167ffffffffffffffff8111156200353f578182fd5b8201601f8101841362003550578182fd5b805162003561620033ac8262003d49565b81815285602083850101111562003576578384fd5b6200358982602083016020860162003d6c565b95945050505050565b600060208284031215620035a4578081fd5b5035919050565b600060208284031215620035bd578081fd5b5051919050565b60008060408385031215620035d7578182fd5b82359150620035e96020840162003372565b90509250929050565b60008060008060008060c087890312156200360b578182fd5b8635955060208701356005811062003621578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600061010080898b03121562003663578586fd5b883597506020808a013567ffffffffffffffff8082111562003683578889fd5b620036918d838e016200338a565b995060408c0135985060608c0135915080821115620036ae578485fd5b620036bc8d838e016200338a565b975060808c0135965060a08c013595508c60df8d0112620036db578485fd5b6040519150604082018281108282111715620036f357fe5b604052508060c08c01848d018e10156200370b578586fd5b8594505b6002851015620037305780358252600194909401939083019083016200370f565b505080935050505092959891949750929550565b60008060006060848603121562003759578081fd5b8335925060208401359150620037726040850162003372565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037c25781516001600160a01b0316875295820195908201906001016200379b565b509495945050505050565b6000815180845260208085019450808401835b83811015620037c257815187529582019590820190600101620037e0565b15159052565b600581106200380f57fe5b9052565b600081518084526200382d81602086016020860162003d6c565b601f01601f19169290920160200192915050565b60006101406200385384845162003804565b60208301518160208601526200386c82860182620037cd565b91505060408301518482036040860152620038888282620037cd565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038c2828262003813565b91505060e083015184820360e0860152620038de828262003813565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025346020830184620037cd565b901515815260200190565b600061010062003982838c62003804565b896020840152886040840152876060840152806080840152620039a88184018862003813565b905082810360a0840152620039be818762003813565b60c0840195909552505060e001529695505050505050565b60006020825262002534602083018462003813565b60006060825262003a00606083018662003813565b828103602084015262003a14818662003813565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a946020830184516200377b565b602083015161016080604085015262003ab261018085018362003788565b9150604085015162003ac860608601826200377b565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b2e8483620037cd565b93508087015191505062003b4582860182620037fe565b5090949350505050565b60006020825262002534602083018462003841565b60006040825262003b79604083018562003841565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d58608083018462003813565b600088825260018060a01b038816602083015286604083015260e0606083015262003bef60e083018762003813565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c6c57607f1988870301845262003c5986835162003813565b9550928401929084019060010162003c3a565b5050505050828103604084015262002d588185620037cd565b60006101008a835280602084015262003ca18184018b620037cd565b9050828103604084015262003cb7818a620037cd565b905087606084015286608084015282810360a084015262003cd9818762003813565b905082810360c084015262003cef818662003813565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d4157fe5b604052919050565b600067ffffffffffffffff82111562003d5e57fe5b50601f01601f191660200190565b60005b8381101562003d8957818101518382015260200162003d6f565b8381111562002c275750506000910152565b801515811462003daa57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212209048116ca0ec76f8f4ed4f0005fb898b46e54e332288727f411707a9e293496264736f6c63430007060033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039d6565b60405180910390f35b620002be620002b836600462003744565b6200068e565b005b620002be620002d1366004620033fe565b620009bb565b620002ee620002e836600462003744565b62000a09565b6040516200029e919062003b88565b620002ee6200030e36600462003592565b62000e42565b620002ee6200032536600462003592565b62000e69565b620002ee6200033c366004620033e1565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e919062003951565b620002ee62001058565b620003796200105e565b6040516200029e919062003900565b6200039f6200039936600462003592565b6200106d565b6040516200029e919062003966565b620003c5620003bf36600462003592565b620011f7565b6040516200029e919062003b4f565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003592565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033e1565b620014b6565b620002be6200044536600462003592565b62001572565b620002ee6200045c366004620035c4565b6200158f565b620003566200047336600462003646565b620019b1565b620002ee6200048a36600462003592565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003592565b62001a1f565b6040516200029e98979695949392919062003971565b620002ee620004e236600462003592565b62001b85565b62000356620004f936600462003592565b62001b8c565b6200037962001c36565b620002be6200051a36600462003592565b62001c45565b6200037962001c62565b620002be6200053b366004620033e1565b62001c71565b620002ee6200055236600462003439565b62001cdd565b6200056f6200056936600462003592565b62001d2b565b6040516200029e919062003a7e565b620002ee62001eca565b620002be62000599366004620035f2565b62001ed0565b6200039f620005b0366004620033e1565b62002444565b620005cd620005c736600462003592565b620024ae565b6040516200029e92919062003b64565b620002ee620005ee36600462003592565b620024e7565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003914565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034f7565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003938565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003d05565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003938565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250990919063ffffffff16565b906200253b565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250990919063ffffffff16565b905062000cdc8162000cd5858562002551565b9062002551565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003938565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034f7565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b88565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034f7565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003d05565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003938565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034f7565b505b905090565b6060600062000f8f62002567565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b6565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003161565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003938565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034f7565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a53565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177190339060040162003900565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035ab565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250990919063ffffffff16565b905062001821828262002551565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003938565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034f7565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f919081019062003516565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bc0565b60405180910390a25091979650505050505050565b6010546060906001600160a01b03163314620019cc57600080fd5b620019d982888762002622565b9050620019f68882620019eb62002672565b868a898d8c62002697565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c8957600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d235762001d1862001d1086838151811062001d0157fe5b6020026020010151866200158f565b839062002859565b915060010162001ce2565b509392505050565b62001d35620031b5565b600a54821062001d515762001d496200286c565b905062000e64565b600a828154811062001d5f57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc4575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001ea857602002820191906000526020600020905b81548152602001906001019080831162001e93575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b6010546001600160a01b0316331462001ee857600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0957fe5b1462001f1457600080fd5b600286600481111562001f2357fe5b60ff16101562001f3257600080fd5b60408051610140810190915281546200219891908390829060ff16600481111562001f5957fe5b600481111562001f6557fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fba57602002820191906000526020600020905b81548152602001906001019080831162001fa5575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201457602002820191906000526020600020905b81548152602001906001019080831162001fff575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020d85780601f10620020ac57610100808354040283529160200191620020d8565b820191906000526020600020905b815481529060010190602001808311620020ba57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021705780601f10620021445761010080835404028352916020019162002170565b820191906000526020600020905b8154815290600101906020018083116200215257829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028e2565b15620021af57620021a9876200293a565b62002412565b60408051610140810190915281546200241291908390829060ff166004811115620021d657fe5b6004811115620021e257fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223757602002820191906000526020600020905b81548152602001906001019080831162002222575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229157602002820191906000526020600020905b8154815260200190600101908083116200227c575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023555780601f10620023295761010080835404028352916020019162002355565b820191906000526020600020905b8154815290600101906020018083116200233757829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ed5780601f10620023c157610100808354040283529160200191620023ed565b820191906000526020600020905b815481529060010190602001808311620023cf57829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029f0565b80548690829060ff191660018360048111156200242b57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245d57600080fd5b6001600160a01b0382166200247157600080fd5b60005462002489906001600160a01b03168362002a16565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b862003161565b6000600c8381548110620024c857fe5b90600052602060002001549050620024e081620011f7565b9150915091565b600c8181548110620024f857600080fd5b600091825260209091200154905081565b6000826200251a575060006200156c565b828202828482816200252857fe5b04146200253457600080fd5b9392505050565b6000808284816200254857fe5b04949350505050565b6000828211156200256157600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258757fe5b906000526020600020015490506200259f81620025b6565b15620025ac576001909201915b506001016200256c565b600080620025c48362001b8c565b90506000805b825181101562001d23576000838281518110620025e357fe5b602002602001015190508060001415801562002607575062002605816200106d565b155b156200261857600192505062001d23565b50600101620025ca565b604080516001808252818301909252606091602080830190803683370190505090506200265184848462002a1a565b816000815181106200265f57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b557fe5b14620026d55760405162461bcd60e51b8152600401620015bb9062003a2d565b60005b8751811015620027185788600d60008a8481518110620026f457fe5b602090810291909101810151825281019190915260400160002055600101620026d8565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff19168317815589516200277a9391909101918a019062003223565b506000888152600b602090815260409091208751620027a29260029092019189019062003223565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027df9260069092019185019062003273565b506000888152600b602090815260409091208251620028079260079092019184019062003273565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284798979695949392919062003c85565b60405180910390a15050505050505050565b6000828201838110156200253457600080fd5b62002876620031b5565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620028f857fe5b60808a015160a08b0151929091141592508714159086141583806200291a5750825b80620029235750815b806200292c5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200299557602002820191906000526020600020905b81548152602001906001019080831162002980575b5050505050905060005b8151811015620029eb576000828281518110620029b857fe5b602002602001015190508060001415620029d35750620029e2565b620029e081600062002ae2565b505b6001016200299f565b505050565b620029eb836020015160008151811062002a0657fe5b6020026020010151838362002c0b565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ada939192909183018282801562002aae5780601f1062002a825761010080835404028352916020019162002aae565b820191906000526020600020905b81548152906001019060200180831162002a9057829003601f168201915b5050505050848462002ad48860016002811062002ac757fe5b6020020151895162002c2d565b62002d37565b949350505050565b6000600a838154811062002af257fe5b90600052602060002090600b02019050600081600101838154811062002b1457fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b9357600080fd5b505afa15801562002ba8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bd2919081019062003516565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b91565b600062002c19838362002d62565b905062002c27848262002ae2565b50505050565b6060600062002c3c8462002d91565b9050600062002c4b8462002d91565b905081810162002c6a8162000c916802a802f8630a2400008662002509565b925062002c868162000c916802a802f8630a2400008562002509565b9150670de0b6b3a764000083101562002c9e57600080fd5b670de0b6b3a764000082101562002cb457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002cec57fe5b602002602001018181525050828460018151811062002d0757fe5b602002602001018181525050818460028151811062002d2257fe5b60200260200101818152505050505092915050565b60008062002d4786868662002df3565b905062002d58338285600162002e78565b9695505050505050565b60008183111562002d76575060026200156c565b8183101562002d88575060016200156c565b5060006200156c565b60008082121562002dd057600082900362002dc762002db282606462002859565b62000c91836802a802f8630a24000062002509565b91505062000e64565b62001d4962002de183606462002859565b690109a12906aff6100000906200253b565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e0b579050509050838160008151811062002e3257fe5b6020026020010181905250818160018151811062002e4c57fe5b6020026020010181905250828160028151811062002e6657fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002ea787306200306c565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f4793928501929190910190620032f5565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fc991600984019160209091019062003223565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200301c9083908790879062003c0e565b60405180910390a1811562002ada577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200305c919062003b88565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308b57600080fd5b50604051908082528060200260200182016040528015620030b6578160200160208202803683370190505b50905060005b828110156200315857858181518110620030d257fe5b6020026020010151868281518110620030e757fe5b602002602001015186604051620030fe906200334d565b6200310c93929190620039eb565b604051809103906000f08015801562003129573d6000803e3d6000fd5b508282815181106200313757fe5b6001600160a01b0390921660209283029190910190910152600101620030bc565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182559160200191906001019062003244565b506200326f9291506200335b565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ab576000855562003261565b82601f10620032c657805160ff191683800117855562003261565b828001600101855582156200326157918201828111156200326157825182559160200191906001019062003244565b82805482825590600052602060002090810192821562003261579160200282015b828111156200326157825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003316565b6111f38062003dae83390190565b5b808211156200326f57600081556001016200335c565b80356001600160a01b038116811462000e6457600080fd5b600082601f8301126200339b578081fd5b8135620033b2620033ac8262003d49565b62003d24565b818152846020838601011115620033c7578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033f3578081fd5b620025348262003372565b6000806040838503121562003411578081fd5b6200341c8362003372565b915060208301356200342e8162003d9b565b809150509250929050565b600080604083850312156200344c578182fd5b823567ffffffffffffffff8082111562003464578384fd5b818501915085601f83011262003478578384fd5b81356020828211156200348757fe5b80820292506200349981840162003d24565b8281528181019085830185870184018b1015620034b4578889fd5b8896505b84871015620034d8578035835260019690960195918301918301620034b8565b509650620034ea905087820162003372565b9450505050509250929050565b60006020828403121562003509578081fd5b8151620025348162003d9b565b60006020828403121562003528578081fd5b815167ffffffffffffffff8111156200353f578182fd5b8201601f8101841362003550578182fd5b805162003561620033ac8262003d49565b81815285602083850101111562003576578384fd5b6200358982602083016020860162003d6c565b95945050505050565b600060208284031215620035a4578081fd5b5035919050565b600060208284031215620035bd578081fd5b5051919050565b60008060408385031215620035d7578182fd5b82359150620035e96020840162003372565b90509250929050565b60008060008060008060c087890312156200360b578182fd5b8635955060208701356005811062003621578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600061010080898b03121562003663578586fd5b883597506020808a013567ffffffffffffffff8082111562003683578889fd5b620036918d838e016200338a565b995060408c0135985060608c0135915080821115620036ae578485fd5b620036bc8d838e016200338a565b975060808c0135965060a08c013595508c60df8d0112620036db578485fd5b6040519150604082018281108282111715620036f357fe5b604052508060c08c01848d018e10156200370b578586fd5b8594505b6002851015620037305780358252600194909401939083019083016200370f565b505080935050505092959891949750929550565b60008060006060848603121562003759578081fd5b8335925060208401359150620037726040850162003372565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037c25781516001600160a01b0316875295820195908201906001016200379b565b509495945050505050565b6000815180845260208085019450808401835b83811015620037c257815187529582019590820190600101620037e0565b15159052565b600581106200380f57fe5b9052565b600081518084526200382d81602086016020860162003d6c565b601f01601f19169290920160200192915050565b60006101406200385384845162003804565b60208301518160208601526200386c82860182620037cd565b91505060408301518482036040860152620038888282620037cd565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038c2828262003813565b91505060e083015184820360e0860152620038de828262003813565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025346020830184620037cd565b901515815260200190565b600061010062003982838c62003804565b896020840152886040840152876060840152806080840152620039a88184018862003813565b905082810360a0840152620039be818762003813565b60c0840195909552505060e001529695505050505050565b60006020825262002534602083018462003813565b60006060825262003a00606083018662003813565b828103602084015262003a14818662003813565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a946020830184516200377b565b602083015161016080604085015262003ab261018085018362003788565b9150604085015162003ac860608601826200377b565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b2e8483620037cd565b93508087015191505062003b4582860182620037fe565b5090949350505050565b60006020825262002534602083018462003841565b60006040825262003b79604083018562003841565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d58608083018462003813565b600088825260018060a01b038816602083015286604083015260e0606083015262003bef60e083018762003813565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c6c57607f1988870301845262003c5986835162003813565b9550928401929084019060010162003c3a565b5050505050828103604084015262002d588185620037cd565b60006101008a835280602084015262003ca18184018b620037cd565b9050828103604084015262003cb7818a620037cd565b905087606084015286608084015282810360a084015262003cd9818762003813565b905082810360c084015262003cef818662003813565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d4157fe5b604052919050565b600067ffffffffffffffff82111562003d5e57fe5b50601f01601f191660200190565b60005b8381101562003d8957818101518382015260200162003d6f565b8381111562002c275750506000910152565b801515811462003daa57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212209048116ca0ec76f8f4ed4f0005fb898b46e54e332288727f411707a9e293496264736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { @@ -1437,8 +1437,8 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(OwnedERC20)25830)dyn_storage": { - "base": "t_contract(OwnedERC20)25830", + "t_array(t_contract(OwnedERC20)25781)dyn_storage": { + "base": "t_contract(OwnedERC20)25781", "encoding": "dynamic_array", "label": "contract OwnedERC20[]", "numberOfBytes": "32" @@ -1476,7 +1476,7 @@ "label": "contract IERC20Full", "numberOfBytes": "20" }, - "t_contract(OwnedERC20)25830": { + "t_contract(OwnedERC20)25781": { "encoding": "inplace", "label": "contract OwnedERC20", "numberOfBytes": "20" @@ -1535,7 +1535,7 @@ "label": "shareTokens", "offset": 0, "slot": "1", - "type": "t_array(t_contract(OwnedERC20)25830)dyn_storage" + "type": "t_array(t_contract(OwnedERC20)25781)dyn_storage" }, { "astId": 15185, @@ -1543,7 +1543,7 @@ "label": "winner", "offset": 0, "slot": "2", - "type": "t_contract(OwnedERC20)25830" + "type": "t_contract(OwnedERC20)25781" }, { "astId": 15187, diff --git a/packages/smart/deployments/maticMumbai/MMAMarketFactoryV3.json b/packages/smart/deployments/maticMumbai/MMAMarketFactoryV3.json index 1130ff804..4c0ee7247 100644 --- a/packages/smart/deployments/maticMumbai/MMAMarketFactoryV3.json +++ b/packages/smart/deployments/maticMumbai/MMAMarketFactoryV3.json @@ -1,5 +1,5 @@ { - "address": "0xEB9FfEd2fef65576577cD88d62E557e364225a1f", + "address": "0x9213E2Ce5D0Eb030Aaccce61685e0453a8426947", "abi": [ { "inputs": [ @@ -1199,35 +1199,35 @@ "type": "function" } ], - "transactionHash": "0x6a50691417aaa9ba4d881965867aeb07f33c02ab5311ee890e97c41c58e78c04", + "transactionHash": "0x5c859d8cf64fd55ef9b08119b273609258b1c6edf5b284d82aee51280d63fc1b", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0xEB9FfEd2fef65576577cD88d62E557e364225a1f", + "contractAddress": "0x9213E2Ce5D0Eb030Aaccce61685e0453a8426947", "transactionIndex": 1, "gasUsed": "4767052", - "logsBloom": "0x00400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000010000800000000000000000080100000000200000000000000000000000000000000000000000000000000080200400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x91ba78c8a3d4ca488daba91bcb3423924882f9d07772a7664b7dff9f855cd094", - "transactionHash": "0x6a50691417aaa9ba4d881965867aeb07f33c02ab5311ee890e97c41c58e78c04", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000004000000000080100000000200000000000000000000000000000000000080000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220800000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", + "blockHash": "0x3c782cc6c8517772a89911f402354a2d0ac2be1e1d970773e4586fa796c96200", + "transactionHash": "0x5c859d8cf64fd55ef9b08119b273609258b1c6edf5b284d82aee51280d63fc1b", "logs": [ { "transactionIndex": 1, - "blockNumber": 19809870, - "transactionHash": "0x6a50691417aaa9ba4d881965867aeb07f33c02ab5311ee890e97c41c58e78c04", + "blockNumber": 20388718, + "transactionHash": "0x5c859d8cf64fd55ef9b08119b273609258b1c6edf5b284d82aee51280d63fc1b", "address": "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x000000000000000000000000eb9ffed2fef65576577cd88d62e557e364225a1f", + "0x0000000000000000000000009213e2ce5d0eb030aaccce61685e0453a8426947", "0x00000000000000000000000059ddfe9961e050bda1ed9bf9ccd009948036dd76" ], "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "logIndex": 2, - "blockHash": "0x91ba78c8a3d4ca488daba91bcb3423924882f9d07772a7664b7dff9f855cd094" + "logIndex": 1, + "blockHash": "0x3c782cc6c8517772a89911f402354a2d0ac2be1e1d970773e4586fa796c96200" }, { "transactionIndex": 1, - "blockNumber": 19809870, - "transactionHash": "0x6a50691417aaa9ba4d881965867aeb07f33c02ab5311ee890e97c41c58e78c04", + "blockNumber": 20388718, + "transactionHash": "0x5c859d8cf64fd55ef9b08119b273609258b1c6edf5b284d82aee51280d63fc1b", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -1235,13 +1235,13 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x0000000000000000000000000000000000000000000000000032ced35b41e800000000000000000000000000000000000000000000000003646e453f40a50829000000000000000000000000000000000000000000000000025fc7f23810b400000000000000000000000000000000000000000000000003643b766be5632029000000000000000000000000000000000000000000000000029296c593529c00", - "logIndex": 3, - "blockHash": "0x91ba78c8a3d4ca488daba91bcb3423924882f9d07772a7664b7dff9f855cd094" + "data": "0x0000000000000000000000000000000000000000000000000032ced35b41e800000000000000000000000000000000000000000000000003350d988a8cb21074000000000000000000000000000000000000000000000000034ff9b56b1a82f000000000000000000000000000000000000000000000000334dac9b7317028740000000000000000000000000000000000000000000000000382c888c65c6af0", + "logIndex": 2, + "blockHash": "0x3c782cc6c8517772a89911f402354a2d0ac2be1e1d970773e4586fa796c96200" } ], - "blockNumber": 19809870, - "cumulativeGasUsed": "4875666", + "blockNumber": 20388718, + "cumulativeGasUsed": "5518016", "status": 1, "byzantium": true }, @@ -1258,10 +1258,10 @@ "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1" ], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_whoWon\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/MMAMarketFactoryV3.sol\":\"MMAMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405260006007553480156200001657600080fd5b50604051620056523803806200565283398101604081905262000039916200052c565b6040805180820182526006815265076312e322e360d41b602080830191909152825180840190935260118352704e6f20436f6e74657374202f204472617760781b90830152600080546001600160a01b03808c166001600160a01b03199283163317831617835560018054828d1690841617905560098a905560028054918a16919092161790559091838a8a8a8a8a8a8189602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b390620001349086906000199060040162000648565b602060405180830381600087803b1580156200014f57600080fd5b505af115801562000164573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018a91906200061f565b50600a62000197620002f5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001ee939285019291909101906200036b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162000270916009840191602090910190620003d5565b506101409190910151600a909101805460ff19169115159190911790555050600e80546001600160a01b0319166001600160a01b039690961695909517909455505050600f839055508051620002ce90601090602084019062000413565b50508151620002e69150601190602084019062000413565b5050505050505050506200067a565b620002ff62000495565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b828054828255906000526020600020908101928215620003c3579160200282015b82811115620003c357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200038c565b50620003d192915062000503565b5090565b828054828255906000526020600020908101928215620003c3579160200282015b82811115620003c3578251825591602001919060010190620003f6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200044b5760008555620003c3565b82601f106200046657805160ff1916838001178555620003c3565b82800160010185558215620003c35791820182811115620003c3578251825591602001919060010190620003f6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003d1576000815560010162000504565b8051620005278162000661565b919050565b6000806000806000806000610120888a03121562000548578283fd5b8751620005558162000661565b809750506020808901516200056a8162000661565b60408a015160608b01519198509650620005848162000661565b9450609f89018a1362000595578384fd5b604051606081016001600160401b0381118282101715620005b257fe5b6040528060808b0160e08c018d811115620005cb578788fd5b875b6003811015620005ec57825184529285019291850191600101620005cd565b50839750620005fb816200051a565b965050505050506200061161010089016200051a565b905092959891949750929550565b60006020828403121562000631578081fd5b8151801515811462000641578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200067757600080fd5b50565b614fc8806200068a6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063eb44fdd31162000087578063eb44fdd3146200056f578063ec9790821462000595578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063dd0f9618146200052a578063e2c30b151462000541578063e5678dfa14620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039c4565b60405180910390f35b620002be620002b836600462003732565b6200068e565b005b620002be620002d1366004620033f4565b620009bb565b620002ee620002e836600462003732565b62000a09565b6040516200029e919062003b76565b620002ee6200030e36600462003588565b62000e42565b620002ee6200032536600462003588565b62000e69565b620002ee6200033c366004620033d7565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e91906200393f565b620002ee62001058565b620003796200105e565b6040516200029e9190620038ee565b6200039f6200039936600462003588565b6200106d565b6040516200029e919062003954565b620003c5620003bf36600462003588565b620011f7565b6040516200029e919062003b3d565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003588565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033d7565b620014b6565b620002be6200044536600462003588565b62001572565b620002ee6200045c366004620035ba565b6200158f565b620003566200047336600462003634565b620019b1565b620002ee6200048a36600462003588565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003588565b62001a1f565b6040516200029e9897969594939291906200395f565b620002ee620004e236600462003588565b62001b85565b62000356620004f936600462003588565b62001b8c565b6200037962001c36565b620002be6200051a36600462003588565b62001c45565b6200037962001c62565b620002be6200053b366004620035e8565b62001c71565b620002be62000552366004620033d7565b620021e1565b620002ee620005693660046200342f565b6200224d565b620005866200058036600462003588565b6200229b565b6040516200029e919062003a6c565b620002ee6200243a565b6200039f620005b0366004620033d7565b62002440565b620005cd620005c736600462003588565b620024aa565b6040516200029e92919062003b52565b620002ee620005ee36600462003588565b620024e3565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003902565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034ed565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003926565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cf3565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003926565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250590919063ffffffff16565b9062002537565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250590919063ffffffff16565b905062000cdc8162000cd585856200254d565b906200254d565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003926565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034ed565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b76565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034ed565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cf3565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003926565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034ed565b505b905090565b6060600062000f8f62002563565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b2565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003157565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003926565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034ed565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a41565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001771903390600401620038ee565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035a1565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250590919063ffffffff16565b90506200182182826200254d565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003926565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034ed565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f91908101906200350c565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bae565b60405180910390a25091979650505050505050565b600e546060906001600160a01b03163314620019cc57600080fd5b620019d98288876200261e565b9050620019f68882620019eb6200266e565b868a898d8c62002693565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b600e546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b600e546001600160a01b0316331462001c8957600080fd5b6000858152600b602052604090206001815460ff16600481111562001caa57fe5b1462001cb557600080fd5b600185600481111562001cc457fe5b141562001cd057600080fd5b604080516101408101909152815462001f3591908390829060ff16600481111562001cf757fe5b600481111562001d0357fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001d5857602002820191906000526020600020905b81548152602001906001019080831162001d43575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001db257602002820191906000526020600020905b81548152602001906001019080831162001d9d575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001e765780601f1062001e4a5761010080835404028352916020019162001e76565b820191906000526020600020905b81548152906001019060200180831162001e5857829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801562001f0e5780601f1062001ee25761010080835404028352916020019162001f0e565b820191906000526020600020905b81548152906001019060200180831162001ef057829003601f168201915b50505050508152602001600882015481526020016009820154815250508686868662002855565b1562001f4c5762001f4686620028ad565b620021ae565b6040805161014081019091528154620021ae91908390829060ff16600481111562001f7357fe5b600481111562001f7f57fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fd457602002820191906000526020600020905b81548152602001906001019080831162001fbf575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200202e57602002820191906000526020600020905b81548152602001906001019080831162002019575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020f25780601f10620020c657610100808354040283529160200191620020f2565b820191906000526020600020905b815481529060010190602001808311620020d457829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200218a5780601f106200215e576101008083540402835291602001916200218a565b820191906000526020600020905b8154815290600101906020018083116200216c57829003601f168201915b50505050508152602001600882015481526020016009820154815250508362002963565b6000868152600b60205260409020805486919060ff19166001836004811115620021d457fe5b0217905550505050505050565b6000546001600160a01b03163314620021f957600080fd5b600e80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b8451811015620022935762002288620022808683815181106200227157fe5b6020026020010151866200158f565b83906200298c565b915060010162002252565b509392505050565b620022a5620031ab565b600a548210620022c157620022b96200299f565b905062000e64565b600a8281548110620022cf57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162002334575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200241857602002820191906000526020600020905b81548152602001906001019080831162002403575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b600080546001600160a01b031633146200245957600080fd5b6001600160a01b0382166200246d57600080fd5b60005462002485906001600160a01b03168362002988565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b462003157565b6000600c8381548110620024c457fe5b90600052602060002001549050620024dc81620011f7565b9150915091565b600c8181548110620024f457600080fd5b600091825260209091200154905081565b60008262002516575060006200156c565b828202828482816200252457fe5b04146200253057600080fd5b9392505050565b6000808284816200254457fe5b04949350505050565b6000828211156200255d57600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258357fe5b906000526020600020015490506200259b81620025b2565b15620025a8576001909201915b5060010162002568565b600080620025c08362001b8c565b90506000805b825181101562002293576000838281518110620025df57fe5b602002602001015190508060001415801562002603575062002601816200106d565b155b156200261457600192505062002293565b50600101620025c6565b604080516001808252818301909252606091602080830190803683370190505090506200264d84848462002a15565b816000815181106200265b57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b157fe5b14620026d15760405162461bcd60e51b8152600401620015bb9062003a1b565b60005b8751811015620027145788600d60008a8481518110620026f057fe5b602090810291909101810151825281019190915260400160002055600101620026d4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027769391909101918a019062003219565b506000888152600b6020908152604090912087516200279e9260029092019189019062003219565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027db9260069092019185019062003269565b506000888152600b602090815260409091208251620028039260079092019184019062003269565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284398979695949392919062003c73565b60405180910390a15050505050505050565b6000600382148160028760048111156200286b57fe5b60808a015160a08b0151929091141592508714159086141583806200288d5750825b80620028965750815b806200289f5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200290857602002820191906000526020600020905b815481526020019060010190808311620028f3575b5050505050905060005b81518110156200295e5760008282815181106200292b57fe5b60200260200101519050806000141562002946575062002955565b6200295381600062002add565b505b60010162002912565b505050565b6200298882602001516000815181106200297957fe5b60200260200101518262002c06565b5050565b6000828201838110156200253057600080fd5b620029a9620031ab565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ad5939192909183018282801562002aa95780601f1062002a7d5761010080835404028352916020019162002aa9565b820191906000526020600020905b81548152906001019060200180831162002a8b57829003601f168201915b5050505050848462002acf8860016002811062002ac257fe5b6020020151895162002c21565b62002d2b565b949350505050565b6000600a838154811062002aed57fe5b90600052602060002090600b02019050600081600101838154811062002b0f57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b8e57600080fd5b505afa15801562002ba3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bcd91908101906200350c565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b7f565b600062002c138262002d56565b90506200295e838262002add565b6060600062002c308462002d87565b9050600062002c3f8462002d87565b905081810162002c5e8162000c916802a802f8630a2400008662002505565b925062002c7a8162000c916802a802f8630a2400008562002505565b9150670de0b6b3a764000083101562002c9257600080fd5b670de0b6b3a764000082101562002ca857600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002ce057fe5b602002602001018181525050828460018151811062002cfb57fe5b602002602001018181525050818460028151811062002d1657fe5b60200260200101818152505050505092915050565b60008062002d3b86868662002de9565b905062002d4c338285600162002e6e565b9695505050505050565b6000816001141562002d6b5750600262000e64565b816002141562002d7e5750600162000e64565b50600062000e64565b60008082121562002dc657600082900362002dbd62002da88260646200298c565b62000c91836802a802f8630a24000062002505565b91505062000e64565b620022b962002dd78360646200298c565b690109a12906aff61000009062002537565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e01579050509050838160008151811062002e2857fe5b6020026020010181905250818160018151811062002e4257fe5b6020026020010181905250828160028151811062002e5c57fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002e9d873062003062565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f3d93928501929190910190620032eb565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fbf91600984019160209091019062003219565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620030129083908790879062003bfc565b60405180910390a1811562002ad5577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f888160405162003052919062003b76565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308157600080fd5b50604051908082528060200260200182016040528015620030ac578160200160208202803683370190505b50905060005b828110156200314e57858181518110620030c857fe5b6020026020010151868281518110620030dd57fe5b602002602001015186604051620030f49062003343565b6200310293929190620039d9565b604051809103906000f0801580156200311f573d6000803e3d6000fd5b508282815181106200312d57fe5b6001600160a01b0390921660209283029190910190910152600101620030b2565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003257579160200282015b82811115620032575782518255916020019190600101906200323a565b506200326592915062003351565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032a1576000855562003257565b82601f10620032bc57805160ff191683800117855562003257565b82800160010185558215620032575791820182811115620032575782518255916020019190600101906200323a565b82805482825590600052602060002090810192821562003257579160200282015b828111156200325757825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200330c565b6111f38062003da083390190565b5b8082111562003265576000815560010162003352565b80356001600160a01b038116811462000e6457600080fd5b600082601f83011262003391578081fd5b8135620033a8620033a28262003d37565b62003d12565b818152846020838601011115620033bd578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033e9578081fd5b620025308262003368565b6000806040838503121562003407578081fd5b620034128362003368565b91506020830135620034248162003d8d565b809150509250929050565b6000806040838503121562003442578182fd5b823567ffffffffffffffff808211156200345a578384fd5b818501915085601f8301126200346e578384fd5b81356020828211156200347d57fe5b80820292506200348f81840162003d12565b8281528181019085830185870184018b1015620034aa578889fd5b8896505b84871015620034ce578035835260019690960195918301918301620034ae565b509650620034e0905087820162003368565b9450505050509250929050565b600060208284031215620034ff578081fd5b8151620025308162003d8d565b6000602082840312156200351e578081fd5b815167ffffffffffffffff81111562003535578182fd5b8201601f8101841362003546578182fd5b805162003557620033a28262003d37565b8181528560208385010111156200356c578384fd5b6200357f82602083016020860162003d5a565b95945050505050565b6000602082840312156200359a578081fd5b5035919050565b600060208284031215620035b3578081fd5b5051919050565b60008060408385031215620035cd578182fd5b82359150620035df6020840162003368565b90509250929050565b600080600080600060a0868803121562003600578081fd5b8535945060208601356005811062003616578182fd5b94979496505050506040830135926060810135926080909101359150565b600080600080600080600061010080898b03121562003651578586fd5b883597506020808a013567ffffffffffffffff8082111562003671578889fd5b6200367f8d838e0162003380565b995060408c0135985060608c01359150808211156200369c578586fd5b620036aa8d838e0162003380565b975060808c0135965060a08c013595508c60df8d0112620036c9578485fd5b6040519150604082018281108282111715620036e157fe5b604052508060c08c01848d018e1015620036f9578586fd5b8594505b60028510156200371e578035825260019490940193908301908301620036fd565b505080935050505092959891949750929550565b60008060006060848603121562003747578081fd5b8335925060208401359150620037606040850162003368565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037b05781516001600160a01b03168752958201959082019060010162003789565b509495945050505050565b6000815180845260208085019450808401835b83811015620037b057815187529582019590820190600101620037ce565b15159052565b60058110620037fd57fe5b9052565b600081518084526200381b81602086016020860162003d5a565b601f01601f19169290920160200192915050565b600061014062003841848451620037f2565b60208301518160208601526200385a82860182620037bb565b91505060408301518482036040860152620038768282620037bb565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038b0828262003801565b91505060e083015184820360e0860152620038cc828262003801565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025306020830184620037bb565b901515815260200190565b600061010062003970838c620037f2565b896020840152886040840152876060840152806080840152620039968184018862003801565b905082810360a0840152620039ac818762003801565b60c0840195909552505060e001529695505050505050565b60006020825262002530602083018462003801565b600060608252620039ee606083018662003801565b828103602084015262003a02818662003801565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a8260208301845162003769565b602083015161016080604085015262003aa061018085018362003776565b9150604085015162003ab6606086018262003769565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b1c8483620037bb565b93508087015191505062003b3382860182620037ec565b5090949350505050565b6000602082526200253060208301846200382f565b60006040825262003b6760408301856200382f565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d4c608083018462003801565b600088825260018060a01b038816602083015286604083015260e0606083015262003bdd60e083018762003801565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5a57607f1988870301845262003c4786835162003801565b9550928401929084019060010162003c28565b5050505050828103604084015262002d4c8185620037bb565b60006101008a835280602084015262003c8f8184018b620037bb565b9050828103604084015262003ca5818a620037bb565b905087606084015286608084015282810360a084015262003cc7818762003801565b905082810360c084015262003cdd818662003801565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2f57fe5b604052919050565b600067ffffffffffffffff82111562003d4c57fe5b50601f01601f191660200190565b60005b8381101562003d7757818101518382015260200162003d5d565b8381111562003d87576000848401525b50505050565b801515811462003d9c57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212208d92a5926f76014c46a7e5c973cb2fac15b1516f21d457b619019fb178ff625a64736f6c63430007060033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063eb44fdd31162000087578063eb44fdd3146200056f578063ec9790821462000595578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063dd0f9618146200052a578063e2c30b151462000541578063e5678dfa14620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039c4565b60405180910390f35b620002be620002b836600462003732565b6200068e565b005b620002be620002d1366004620033f4565b620009bb565b620002ee620002e836600462003732565b62000a09565b6040516200029e919062003b76565b620002ee6200030e36600462003588565b62000e42565b620002ee6200032536600462003588565b62000e69565b620002ee6200033c366004620033d7565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e91906200393f565b620002ee62001058565b620003796200105e565b6040516200029e9190620038ee565b6200039f6200039936600462003588565b6200106d565b6040516200029e919062003954565b620003c5620003bf36600462003588565b620011f7565b6040516200029e919062003b3d565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003588565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033d7565b620014b6565b620002be6200044536600462003588565b62001572565b620002ee6200045c366004620035ba565b6200158f565b620003566200047336600462003634565b620019b1565b620002ee6200048a36600462003588565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003588565b62001a1f565b6040516200029e9897969594939291906200395f565b620002ee620004e236600462003588565b62001b85565b62000356620004f936600462003588565b62001b8c565b6200037962001c36565b620002be6200051a36600462003588565b62001c45565b6200037962001c62565b620002be6200053b366004620035e8565b62001c71565b620002be62000552366004620033d7565b620021e1565b620002ee620005693660046200342f565b6200224d565b620005866200058036600462003588565b6200229b565b6040516200029e919062003a6c565b620002ee6200243a565b6200039f620005b0366004620033d7565b62002440565b620005cd620005c736600462003588565b620024aa565b6040516200029e92919062003b52565b620002ee620005ee36600462003588565b620024e3565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003902565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034ed565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003926565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cf3565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003926565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250590919063ffffffff16565b9062002537565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250590919063ffffffff16565b905062000cdc8162000cd585856200254d565b906200254d565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003926565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034ed565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b76565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034ed565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cf3565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003926565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034ed565b505b905090565b6060600062000f8f62002563565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b2565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003157565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003926565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034ed565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a41565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001771903390600401620038ee565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035a1565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250590919063ffffffff16565b90506200182182826200254d565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003926565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034ed565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f91908101906200350c565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bae565b60405180910390a25091979650505050505050565b600e546060906001600160a01b03163314620019cc57600080fd5b620019d98288876200261e565b9050620019f68882620019eb6200266e565b868a898d8c62002693565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b600e546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b600e546001600160a01b0316331462001c8957600080fd5b6000858152600b602052604090206001815460ff16600481111562001caa57fe5b1462001cb557600080fd5b600185600481111562001cc457fe5b141562001cd057600080fd5b604080516101408101909152815462001f3591908390829060ff16600481111562001cf757fe5b600481111562001d0357fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001d5857602002820191906000526020600020905b81548152602001906001019080831162001d43575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001db257602002820191906000526020600020905b81548152602001906001019080831162001d9d575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001e765780601f1062001e4a5761010080835404028352916020019162001e76565b820191906000526020600020905b81548152906001019060200180831162001e5857829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801562001f0e5780601f1062001ee25761010080835404028352916020019162001f0e565b820191906000526020600020905b81548152906001019060200180831162001ef057829003601f168201915b50505050508152602001600882015481526020016009820154815250508686868662002855565b1562001f4c5762001f4686620028ad565b620021ae565b6040805161014081019091528154620021ae91908390829060ff16600481111562001f7357fe5b600481111562001f7f57fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fd457602002820191906000526020600020905b81548152602001906001019080831162001fbf575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200202e57602002820191906000526020600020905b81548152602001906001019080831162002019575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020f25780601f10620020c657610100808354040283529160200191620020f2565b820191906000526020600020905b815481529060010190602001808311620020d457829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200218a5780601f106200215e576101008083540402835291602001916200218a565b820191906000526020600020905b8154815290600101906020018083116200216c57829003601f168201915b50505050508152602001600882015481526020016009820154815250508362002963565b6000868152600b60205260409020805486919060ff19166001836004811115620021d457fe5b0217905550505050505050565b6000546001600160a01b03163314620021f957600080fd5b600e80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b8451811015620022935762002288620022808683815181106200227157fe5b6020026020010151866200158f565b83906200298c565b915060010162002252565b509392505050565b620022a5620031ab565b600a548210620022c157620022b96200299f565b905062000e64565b600a8281548110620022cf57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162002334575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200241857602002820191906000526020600020905b81548152602001906001019080831162002403575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b600080546001600160a01b031633146200245957600080fd5b6001600160a01b0382166200246d57600080fd5b60005462002485906001600160a01b03168362002988565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b462003157565b6000600c8381548110620024c457fe5b90600052602060002001549050620024dc81620011f7565b9150915091565b600c8181548110620024f457600080fd5b600091825260209091200154905081565b60008262002516575060006200156c565b828202828482816200252457fe5b04146200253057600080fd5b9392505050565b6000808284816200254457fe5b04949350505050565b6000828211156200255d57600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258357fe5b906000526020600020015490506200259b81620025b2565b15620025a8576001909201915b5060010162002568565b600080620025c08362001b8c565b90506000805b825181101562002293576000838281518110620025df57fe5b602002602001015190508060001415801562002603575062002601816200106d565b155b156200261457600192505062002293565b50600101620025c6565b604080516001808252818301909252606091602080830190803683370190505090506200264d84848462002a15565b816000815181106200265b57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b157fe5b14620026d15760405162461bcd60e51b8152600401620015bb9062003a1b565b60005b8751811015620027145788600d60008a8481518110620026f057fe5b602090810291909101810151825281019190915260400160002055600101620026d4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027769391909101918a019062003219565b506000888152600b6020908152604090912087516200279e9260029092019189019062003219565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027db9260069092019185019062003269565b506000888152600b602090815260409091208251620028039260079092019184019062003269565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284398979695949392919062003c73565b60405180910390a15050505050505050565b6000600382148160028760048111156200286b57fe5b60808a015160a08b0151929091141592508714159086141583806200288d5750825b80620028965750815b806200289f5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200290857602002820191906000526020600020905b815481526020019060010190808311620028f3575b5050505050905060005b81518110156200295e5760008282815181106200292b57fe5b60200260200101519050806000141562002946575062002955565b6200295381600062002add565b505b60010162002912565b505050565b6200298882602001516000815181106200297957fe5b60200260200101518262002c06565b5050565b6000828201838110156200253057600080fd5b620029a9620031ab565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ad5939192909183018282801562002aa95780601f1062002a7d5761010080835404028352916020019162002aa9565b820191906000526020600020905b81548152906001019060200180831162002a8b57829003601f168201915b5050505050848462002acf8860016002811062002ac257fe5b6020020151895162002c21565b62002d2b565b949350505050565b6000600a838154811062002aed57fe5b90600052602060002090600b02019050600081600101838154811062002b0f57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b8e57600080fd5b505afa15801562002ba3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bcd91908101906200350c565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b7f565b600062002c138262002d56565b90506200295e838262002add565b6060600062002c308462002d87565b9050600062002c3f8462002d87565b905081810162002c5e8162000c916802a802f8630a2400008662002505565b925062002c7a8162000c916802a802f8630a2400008562002505565b9150670de0b6b3a764000083101562002c9257600080fd5b670de0b6b3a764000082101562002ca857600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002ce057fe5b602002602001018181525050828460018151811062002cfb57fe5b602002602001018181525050818460028151811062002d1657fe5b60200260200101818152505050505092915050565b60008062002d3b86868662002de9565b905062002d4c338285600162002e6e565b9695505050505050565b6000816001141562002d6b5750600262000e64565b816002141562002d7e5750600162000e64565b50600062000e64565b60008082121562002dc657600082900362002dbd62002da88260646200298c565b62000c91836802a802f8630a24000062002505565b91505062000e64565b620022b962002dd78360646200298c565b690109a12906aff61000009062002537565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e01579050509050838160008151811062002e2857fe5b6020026020010181905250818160018151811062002e4257fe5b6020026020010181905250828160028151811062002e5c57fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002e9d873062003062565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f3d93928501929190910190620032eb565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fbf91600984019160209091019062003219565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620030129083908790879062003bfc565b60405180910390a1811562002ad5577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f888160405162003052919062003b76565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308157600080fd5b50604051908082528060200260200182016040528015620030ac578160200160208202803683370190505b50905060005b828110156200314e57858181518110620030c857fe5b6020026020010151868281518110620030dd57fe5b602002602001015186604051620030f49062003343565b6200310293929190620039d9565b604051809103906000f0801580156200311f573d6000803e3d6000fd5b508282815181106200312d57fe5b6001600160a01b0390921660209283029190910190910152600101620030b2565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003257579160200282015b82811115620032575782518255916020019190600101906200323a565b506200326592915062003351565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032a1576000855562003257565b82601f10620032bc57805160ff191683800117855562003257565b82800160010185558215620032575791820182811115620032575782518255916020019190600101906200323a565b82805482825590600052602060002090810192821562003257579160200282015b828111156200325757825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200330c565b6111f38062003da083390190565b5b8082111562003265576000815560010162003352565b80356001600160a01b038116811462000e6457600080fd5b600082601f83011262003391578081fd5b8135620033a8620033a28262003d37565b62003d12565b818152846020838601011115620033bd578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033e9578081fd5b620025308262003368565b6000806040838503121562003407578081fd5b620034128362003368565b91506020830135620034248162003d8d565b809150509250929050565b6000806040838503121562003442578182fd5b823567ffffffffffffffff808211156200345a578384fd5b818501915085601f8301126200346e578384fd5b81356020828211156200347d57fe5b80820292506200348f81840162003d12565b8281528181019085830185870184018b1015620034aa578889fd5b8896505b84871015620034ce578035835260019690960195918301918301620034ae565b509650620034e0905087820162003368565b9450505050509250929050565b600060208284031215620034ff578081fd5b8151620025308162003d8d565b6000602082840312156200351e578081fd5b815167ffffffffffffffff81111562003535578182fd5b8201601f8101841362003546578182fd5b805162003557620033a28262003d37565b8181528560208385010111156200356c578384fd5b6200357f82602083016020860162003d5a565b95945050505050565b6000602082840312156200359a578081fd5b5035919050565b600060208284031215620035b3578081fd5b5051919050565b60008060408385031215620035cd578182fd5b82359150620035df6020840162003368565b90509250929050565b600080600080600060a0868803121562003600578081fd5b8535945060208601356005811062003616578182fd5b94979496505050506040830135926060810135926080909101359150565b600080600080600080600061010080898b03121562003651578586fd5b883597506020808a013567ffffffffffffffff8082111562003671578889fd5b6200367f8d838e0162003380565b995060408c0135985060608c01359150808211156200369c578586fd5b620036aa8d838e0162003380565b975060808c0135965060a08c013595508c60df8d0112620036c9578485fd5b6040519150604082018281108282111715620036e157fe5b604052508060c08c01848d018e1015620036f9578586fd5b8594505b60028510156200371e578035825260019490940193908301908301620036fd565b505080935050505092959891949750929550565b60008060006060848603121562003747578081fd5b8335925060208401359150620037606040850162003368565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037b05781516001600160a01b03168752958201959082019060010162003789565b509495945050505050565b6000815180845260208085019450808401835b83811015620037b057815187529582019590820190600101620037ce565b15159052565b60058110620037fd57fe5b9052565b600081518084526200381b81602086016020860162003d5a565b601f01601f19169290920160200192915050565b600061014062003841848451620037f2565b60208301518160208601526200385a82860182620037bb565b91505060408301518482036040860152620038768282620037bb565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038b0828262003801565b91505060e083015184820360e0860152620038cc828262003801565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025306020830184620037bb565b901515815260200190565b600061010062003970838c620037f2565b896020840152886040840152876060840152806080840152620039968184018862003801565b905082810360a0840152620039ac818762003801565b60c0840195909552505060e001529695505050505050565b60006020825262002530602083018462003801565b600060608252620039ee606083018662003801565b828103602084015262003a02818662003801565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a8260208301845162003769565b602083015161016080604085015262003aa061018085018362003776565b9150604085015162003ab6606086018262003769565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b1c8483620037bb565b93508087015191505062003b3382860182620037ec565b5090949350505050565b6000602082526200253060208301846200382f565b60006040825262003b6760408301856200382f565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d4c608083018462003801565b600088825260018060a01b038816602083015286604083015260e0606083015262003bdd60e083018762003801565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5a57607f1988870301845262003c4786835162003801565b9550928401929084019060010162003c28565b5050505050828103604084015262002d4c8185620037bb565b60006101008a835280602084015262003c8f8184018b620037bb565b9050828103604084015262003ca5818a620037bb565b905087606084015286608084015282810360a084015262003cc7818762003801565b905082810360c084015262003cdd818662003801565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2f57fe5b604052919050565b600067ffffffffffffffff82111562003d4c57fe5b50601f01601f191660200190565b60005b8381101562003d7757818101518382015260200162003d5d565b8381111562003d87576000848401525b50505050565b801515811462003d9c57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212208d92a5926f76014c46a7e5c973cb2fac15b1516f21d457b619019fb178ff625a64736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_whoWon\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/MMAMarketFactoryV3.sol\":\"MMAMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006007553480156200001657600080fd5b50604051620056523803806200565283398101604081905262000039916200052c565b6040805180820182526006815265076312e322e360d41b602080830191909152825180840190935260118352704e6f20436f6e74657374202f204472617760781b90830152600080546001600160a01b03808c166001600160a01b03199283163317831617835560018054828d1690841617905560098a905560028054918a16919092161790559091838a8a8a8a8a8a8189602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b390620001349086906000199060040162000648565b602060405180830381600087803b1580156200014f57600080fd5b505af115801562000164573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200018a91906200061f565b50600a62000197620002f5565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001ee939285019291909101906200036b565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162000270916009840191602090910190620003d5565b506101409190910151600a909101805460ff19169115159190911790555050600e80546001600160a01b0319166001600160a01b039690961695909517909455505050600f839055508051620002ce90601090602084019062000413565b50508151620002e69150601190602084019062000413565b5050505050505050506200067a565b620002ff62000495565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b828054828255906000526020600020908101928215620003c3579160200282015b82811115620003c357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200038c565b50620003d192915062000503565b5090565b828054828255906000526020600020908101928215620003c3579160200282015b82811115620003c3578251825591602001919060010190620003f6565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200044b5760008555620003c3565b82601f106200046657805160ff1916838001178555620003c3565b82800160010185558215620003c35791820182811115620003c3578251825591602001919060010190620003f6565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003d1576000815560010162000504565b8051620005278162000661565b919050565b6000806000806000806000610120888a03121562000548578283fd5b8751620005558162000661565b809750506020808901516200056a8162000661565b60408a015160608b01519198509650620005848162000661565b9450609f89018a1362000595578384fd5b604051606081016001600160401b0381118282101715620005b257fe5b6040528060808b0160e08c018d811115620005cb578788fd5b875b6003811015620005ec57825184529285019291850191600101620005cd565b50839750620005fb816200051a565b965050505050506200061161010089016200051a565b905092959891949750929550565b60006020828403121562000631578081fd5b8151801515811462000641578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200067757600080fd5b50565b614fc8806200068a6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063eb44fdd31162000087578063eb44fdd3146200056f578063ec9790821462000595578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063dd0f9618146200052a578063e2c30b151462000541578063e5678dfa14620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039c4565b60405180910390f35b620002be620002b836600462003732565b6200068e565b005b620002be620002d1366004620033f4565b620009bb565b620002ee620002e836600462003732565b62000a09565b6040516200029e919062003b76565b620002ee6200030e36600462003588565b62000e42565b620002ee6200032536600462003588565b62000e69565b620002ee6200033c366004620033d7565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e91906200393f565b620002ee62001058565b620003796200105e565b6040516200029e9190620038ee565b6200039f6200039936600462003588565b6200106d565b6040516200029e919062003954565b620003c5620003bf36600462003588565b620011f7565b6040516200029e919062003b3d565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003588565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033d7565b620014b6565b620002be6200044536600462003588565b62001572565b620002ee6200045c366004620035ba565b6200158f565b620003566200047336600462003634565b620019b1565b620002ee6200048a36600462003588565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003588565b62001a1f565b6040516200029e9897969594939291906200395f565b620002ee620004e236600462003588565b62001b85565b62000356620004f936600462003588565b62001b8c565b6200037962001c36565b620002be6200051a36600462003588565b62001c45565b6200037962001c62565b620002be6200053b366004620035e8565b62001c71565b620002be62000552366004620033d7565b620021e1565b620002ee620005693660046200342f565b6200224d565b620005866200058036600462003588565b6200229b565b6040516200029e919062003a6c565b620002ee6200243a565b6200039f620005b0366004620033d7565b62002440565b620005cd620005c736600462003588565b620024aa565b6040516200029e92919062003b52565b620002ee620005ee36600462003588565b620024e3565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003902565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034ed565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003926565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cf3565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003926565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250590919063ffffffff16565b9062002537565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250590919063ffffffff16565b905062000cdc8162000cd585856200254d565b906200254d565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003926565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034ed565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b76565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034ed565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cf3565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003926565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034ed565b505b905090565b6060600062000f8f62002563565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b2565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003157565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003926565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034ed565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a41565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001771903390600401620038ee565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035a1565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250590919063ffffffff16565b90506200182182826200254d565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003926565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034ed565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f91908101906200350c565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bae565b60405180910390a25091979650505050505050565b600e546060906001600160a01b03163314620019cc57600080fd5b620019d98288876200261e565b9050620019f68882620019eb6200266e565b868a898d8c62002693565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b600e546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b600e546001600160a01b0316331462001c8957600080fd5b6000858152600b602052604090206001815460ff16600481111562001caa57fe5b1462001cb557600080fd5b600185600481111562001cc457fe5b141562001cd057600080fd5b604080516101408101909152815462001f3591908390829060ff16600481111562001cf757fe5b600481111562001d0357fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001d5857602002820191906000526020600020905b81548152602001906001019080831162001d43575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001db257602002820191906000526020600020905b81548152602001906001019080831162001d9d575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001e765780601f1062001e4a5761010080835404028352916020019162001e76565b820191906000526020600020905b81548152906001019060200180831162001e5857829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801562001f0e5780601f1062001ee25761010080835404028352916020019162001f0e565b820191906000526020600020905b81548152906001019060200180831162001ef057829003601f168201915b50505050508152602001600882015481526020016009820154815250508686868662002855565b1562001f4c5762001f4686620028ad565b620021ae565b6040805161014081019091528154620021ae91908390829060ff16600481111562001f7357fe5b600481111562001f7f57fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fd457602002820191906000526020600020905b81548152602001906001019080831162001fbf575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200202e57602002820191906000526020600020905b81548152602001906001019080831162002019575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020f25780601f10620020c657610100808354040283529160200191620020f2565b820191906000526020600020905b815481529060010190602001808311620020d457829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200218a5780601f106200215e576101008083540402835291602001916200218a565b820191906000526020600020905b8154815290600101906020018083116200216c57829003601f168201915b50505050508152602001600882015481526020016009820154815250508362002963565b6000868152600b60205260409020805486919060ff19166001836004811115620021d457fe5b0217905550505050505050565b6000546001600160a01b03163314620021f957600080fd5b600e80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b8451811015620022935762002288620022808683815181106200227157fe5b6020026020010151866200158f565b83906200298c565b915060010162002252565b509392505050565b620022a5620031ab565b600a548210620022c157620022b96200299f565b905062000e64565b600a8281548110620022cf57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162002334575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200241857602002820191906000526020600020905b81548152602001906001019080831162002403575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b600080546001600160a01b031633146200245957600080fd5b6001600160a01b0382166200246d57600080fd5b60005462002485906001600160a01b03168362002988565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b462003157565b6000600c8381548110620024c457fe5b90600052602060002001549050620024dc81620011f7565b9150915091565b600c8181548110620024f457600080fd5b600091825260209091200154905081565b60008262002516575060006200156c565b828202828482816200252457fe5b04146200253057600080fd5b9392505050565b6000808284816200254457fe5b04949350505050565b6000828211156200255d57600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258357fe5b906000526020600020015490506200259b81620025b2565b15620025a8576001909201915b5060010162002568565b600080620025c08362001b8c565b90506000805b825181101562002293576000838281518110620025df57fe5b602002602001015190508060001415801562002603575062002601816200106d565b155b156200261457600192505062002293565b50600101620025c6565b604080516001808252818301909252606091602080830190803683370190505090506200264d84848462002a15565b816000815181106200265b57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b157fe5b14620026d15760405162461bcd60e51b8152600401620015bb9062003a1b565b60005b8751811015620027145788600d60008a8481518110620026f057fe5b602090810291909101810151825281019190915260400160002055600101620026d4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027769391909101918a019062003219565b506000888152600b6020908152604090912087516200279e9260029092019189019062003219565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027db9260069092019185019062003269565b506000888152600b602090815260409091208251620028039260079092019184019062003269565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284398979695949392919062003c73565b60405180910390a15050505050505050565b6000600382148160028760048111156200286b57fe5b60808a015160a08b0151929091141592508714159086141583806200288d5750825b80620028965750815b806200289f5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200290857602002820191906000526020600020905b815481526020019060010190808311620028f3575b5050505050905060005b81518110156200295e5760008282815181106200292b57fe5b60200260200101519050806000141562002946575062002955565b6200295381600062002add565b505b60010162002912565b505050565b6200298882602001516000815181106200297957fe5b60200260200101518262002c06565b5050565b6000828201838110156200253057600080fd5b620029a9620031ab565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ad5939192909183018282801562002aa95780601f1062002a7d5761010080835404028352916020019162002aa9565b820191906000526020600020905b81548152906001019060200180831162002a8b57829003601f168201915b5050505050848462002acf8860016002811062002ac257fe5b6020020151895162002c21565b62002d2b565b949350505050565b6000600a838154811062002aed57fe5b90600052602060002090600b02019050600081600101838154811062002b0f57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b8e57600080fd5b505afa15801562002ba3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bcd91908101906200350c565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b7f565b600062002c138262002d56565b90506200295e838262002add565b6060600062002c308462002d87565b9050600062002c3f8462002d87565b905081810162002c5e8162000c916802a802f8630a2400008662002505565b925062002c7a8162000c916802a802f8630a2400008562002505565b9150670de0b6b3a764000083101562002c9257600080fd5b670de0b6b3a764000082101562002ca857600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002ce057fe5b602002602001018181525050828460018151811062002cfb57fe5b602002602001018181525050818460028151811062002d1657fe5b60200260200101818152505050505092915050565b60008062002d3b86868662002de9565b905062002d4c338285600162002e6e565b9695505050505050565b6000816001141562002d6b5750600262000e64565b816002141562002d7e5750600162000e64565b50600062000e64565b60008082121562002dc657600082900362002dbd62002da88260646200298c565b62000c91836802a802f8630a24000062002505565b91505062000e64565b620022b962002dd78360646200298c565b690109a12906aff61000009062002537565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e01579050509050838160008151811062002e2857fe5b6020026020010181905250818160018151811062002e4257fe5b6020026020010181905250828160028151811062002e5c57fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002e9d873062003062565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f3d93928501929190910190620032eb565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fbf91600984019160209091019062003219565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620030129083908790879062003bfc565b60405180910390a1811562002ad5577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f888160405162003052919062003b76565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308157600080fd5b50604051908082528060200260200182016040528015620030ac578160200160208202803683370190505b50905060005b828110156200314e57858181518110620030c857fe5b6020026020010151868281518110620030dd57fe5b602002602001015186604051620030f49062003343565b6200310293929190620039d9565b604051809103906000f0801580156200311f573d6000803e3d6000fd5b508282815181106200312d57fe5b6001600160a01b0390921660209283029190910190910152600101620030b2565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003257579160200282015b82811115620032575782518255916020019190600101906200323a565b506200326592915062003351565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032a1576000855562003257565b82601f10620032bc57805160ff191683800117855562003257565b82800160010185558215620032575791820182811115620032575782518255916020019190600101906200323a565b82805482825590600052602060002090810192821562003257579160200282015b828111156200325757825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200330c565b6111f38062003da083390190565b5b8082111562003265576000815560010162003352565b80356001600160a01b038116811462000e6457600080fd5b600082601f83011262003391578081fd5b8135620033a8620033a28262003d37565b62003d12565b818152846020838601011115620033bd578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033e9578081fd5b620025308262003368565b6000806040838503121562003407578081fd5b620034128362003368565b91506020830135620034248162003d8d565b809150509250929050565b6000806040838503121562003442578182fd5b823567ffffffffffffffff808211156200345a578384fd5b818501915085601f8301126200346e578384fd5b81356020828211156200347d57fe5b80820292506200348f81840162003d12565b8281528181019085830185870184018b1015620034aa578889fd5b8896505b84871015620034ce578035835260019690960195918301918301620034ae565b509650620034e0905087820162003368565b9450505050509250929050565b600060208284031215620034ff578081fd5b8151620025308162003d8d565b6000602082840312156200351e578081fd5b815167ffffffffffffffff81111562003535578182fd5b8201601f8101841362003546578182fd5b805162003557620033a28262003d37565b8181528560208385010111156200356c578384fd5b6200357f82602083016020860162003d5a565b95945050505050565b6000602082840312156200359a578081fd5b5035919050565b600060208284031215620035b3578081fd5b5051919050565b60008060408385031215620035cd578182fd5b82359150620035df6020840162003368565b90509250929050565b600080600080600060a0868803121562003600578081fd5b8535945060208601356005811062003616578182fd5b94979496505050506040830135926060810135926080909101359150565b600080600080600080600061010080898b03121562003651578586fd5b883597506020808a013567ffffffffffffffff8082111562003671578889fd5b6200367f8d838e0162003380565b995060408c0135985060608c01359150808211156200369c578586fd5b620036aa8d838e0162003380565b975060808c0135965060a08c013595508c60df8d0112620036c9578485fd5b6040519150604082018281108282111715620036e157fe5b604052508060c08c01848d018e1015620036f9578586fd5b8594505b60028510156200371e578035825260019490940193908301908301620036fd565b505080935050505092959891949750929550565b60008060006060848603121562003747578081fd5b8335925060208401359150620037606040850162003368565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037b05781516001600160a01b03168752958201959082019060010162003789565b509495945050505050565b6000815180845260208085019450808401835b83811015620037b057815187529582019590820190600101620037ce565b15159052565b60058110620037fd57fe5b9052565b600081518084526200381b81602086016020860162003d5a565b601f01601f19169290920160200192915050565b600061014062003841848451620037f2565b60208301518160208601526200385a82860182620037bb565b91505060408301518482036040860152620038768282620037bb565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038b0828262003801565b91505060e083015184820360e0860152620038cc828262003801565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025306020830184620037bb565b901515815260200190565b600061010062003970838c620037f2565b896020840152886040840152876060840152806080840152620039968184018862003801565b905082810360a0840152620039ac818762003801565b60c0840195909552505060e001529695505050505050565b60006020825262002530602083018462003801565b600060608252620039ee606083018662003801565b828103602084015262003a02818662003801565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a8260208301845162003769565b602083015161016080604085015262003aa061018085018362003776565b9150604085015162003ab6606086018262003769565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b1c8483620037bb565b93508087015191505062003b3382860182620037ec565b5090949350505050565b6000602082526200253060208301846200382f565b60006040825262003b6760408301856200382f565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d4c608083018462003801565b600088825260018060a01b038816602083015286604083015260e0606083015262003bdd60e083018762003801565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5a57607f1988870301845262003c4786835162003801565b9550928401929084019060010162003c28565b5050505050828103604084015262002d4c8185620037bb565b60006101008a835280602084015262003c8f8184018b620037bb565b9050828103604084015262003ca5818a620037bb565b905087606084015286608084015282810360a084015262003cc7818762003801565b905082810360c084015262003cdd818662003801565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2f57fe5b604052919050565b600067ffffffffffffffff82111562003d4c57fe5b50601f01601f191660200190565b60005b8381101562003d7757818101518382015260200162003d5d565b8381111562003d87576000848401525b50505050565b801515811462003d9c57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a264697066735822122027590c2bfea9ba8c944f7c4df67942d3cfc147534a780651e8f3b40af2f4b31864736f6c63430007060033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d5da4f1d11620000c9578063eb44fdd31162000087578063eb44fdd3146200056f578063ec9790821462000595578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d5da4f1d1462000509578063d8dfeb451462000520578063dd0f9618146200052a578063e2c30b151462000541578063e5678dfa14620005585762000280565b8063b0e21e8a1162000117578063b0e21e8a146200049a578063cb68b0d814620004a4578063cc87adea14620004d1578063cdaac86214620004e8578063d4b6838e14620004ff5762000280565b806397eef1871462000434578063992c9079146200044b5780639c4935691462000462578063a26956151462000479578063a544a62c14620004905762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039c4565b60405180910390f35b620002be620002b836600462003732565b6200068e565b005b620002be620002d1366004620033f4565b620009bb565b620002ee620002e836600462003732565b62000a09565b6040516200029e919062003b76565b620002ee6200030e36600462003588565b62000e42565b620002ee6200032536600462003588565b62000e69565b620002ee6200033c366004620033d7565b62000ea5565b620002ee62000eb7565b6200035662000f81565b6040516200029e91906200393f565b620002ee62001058565b620003796200105e565b6040516200029e9190620038ee565b6200039f6200039936600462003588565b6200106d565b6040516200029e919062003954565b620003c5620003bf36600462003588565b620011f7565b6040516200029e919062003b3d565b620002ee62001469565b620002ee6200146f565b620002be620003f936600462003588565b62001475565b620002ee62001492565b6200037962001498565b62000379620014a7565b620002ee6200042e366004620033d7565b620014b6565b620002be6200044536600462003588565b62001572565b620002ee6200045c366004620035ba565b6200158f565b620003566200047336600462003634565b620019b1565b620002ee6200048a36600462003588565b62001a01565b620002ee62001a13565b620002ee62001a19565b620004bb620004b536600462003588565b62001a1f565b6040516200029e9897969594939291906200395f565b620002ee620004e236600462003588565b62001b85565b62000356620004f936600462003588565b62001b8c565b6200037962001c36565b620002be6200051a36600462003588565b62001c45565b6200037962001c62565b620002be6200053b366004620035e8565b62001c71565b620002be62000552366004620033d7565b620021e1565b620002ee620005693660046200342f565b6200224d565b620005866200058036600462003588565b6200229b565b6040516200029e919062003a6c565b620002ee6200243a565b6200039f620005b0366004620033d7565b62002440565b620005cd620005c736600462003588565b620024aa565b6040516200029e92919062003b52565b620002ee620005ee36600462003588565b620024e3565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e69565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003902565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620007669190620034ed565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003926565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cf3565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb7565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003926565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e69565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250590919063ffffffff16565b9062002537565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250590919063ffffffff16565b905062000cdc8162000cd585856200254d565b906200254d565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003926565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f9190620034ed565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b76565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df89190620034ed565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cf3565b60405180910390a150909695505050505050565b6000818152600d602052604081205462000e5c81620011f7565b606001519150505b919050565b6000600954821015801562000e885750600954828162000e8557fe5b06155b62000e9257600080fd5b600954828162000e9e57fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed357503330145b62000edd57600080fd5b600754801562000f7c57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2492911690859060040162003926565b602060405180830381600087803b15801562000f3f57600080fd5b505af115801562000f54573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7a9190620034ed565b505b905090565b6060600062000f8f62002563565b905060008167ffffffffffffffff8111801562000fab57600080fd5b5060405190808252806020026020018201604052801562000fd6578160200160208202803683370190505b5090506000805b600c548110156200104f578382111562000ff7576200104f565b6000600c82815481106200100757fe5b906000526020600020015490506200101f81620025b2565b156200104557808484815181106200103357fe5b60209081029190910101526001909201915b5060010162000fdd565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200107e57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e3575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c757602002820191906000526020600020905b815481526020019060010190808311620011b2575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b6200120162003157565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200122e57fe5b60048111156200123a57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200128f57602002820191906000526020600020905b8154815260200190600101908083116200127a575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012e957602002820191906000526020600020905b815481526020019060010190808311620012d4575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013ad5780601f106200138157610100808354040283529160200191620013ad565b820191906000526020600020905b8154815290600101906020018083116200138f57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014455780601f10620014195761010080835404028352916020019162001445565b820191906000526020600020905b8154815290600101906020018083116200142757829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148d57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156c573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001514908690859060040162003926565b602060405180830381600087803b1580156200152f57600080fd5b505af115801562001544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156a9190620034ed565b505b92915050565b6000546001600160a01b031633146200158a57600080fd5b600355565b60006200159c836200106d565b620015c45760405162461bcd60e51b8152600401620015bb9062003a41565b60405180910390fd5b6000600a8481548110620015d457fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001639575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171d57602002820191906000526020600020905b81548152602001906001019080831162001708575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001771903390600401620038ee565b602060405180830381600087803b1580156200178c57600080fd5b505af1158015620017a1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c79190620035a1565b90506009546009548281620017d857fe5b040290506000620017e98262000e69565b9050600062001813670de0b6b3a764000062000c918660800151856200250590919063ffffffff16565b90506200182182826200254d565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001870908990869060040162003926565b602060405180830381600087803b1580156200188b57600080fd5b505af1158015620018a0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c69190620034ed565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191057600080fd5b505afa15801562001925573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200194f91908101906200350c565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199c979695949392919062003bae565b60405180910390a25091979650505050505050565b600e546060906001600160a01b03163314620019cc57600080fd5b620019d98288876200261e565b9050620019f68882620019eb6200266e565b868a898d8c62002693565b979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001adb5780601f1062001aaf5761010080835404028352916020019162001adb565b820191906000526020600020905b81548152906001019060200180831162001abd57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b6f5780601f1062001b435761010080835404028352916020019162001b6f565b820191906000526020600020905b81548152906001019060200180831162001b5157829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001bbb57600080fd5b5060405190808252806020026020018201604052801562001be6578160200160208202803683370190505b50925060005b8181101562001c2e5782818154811062001c0257fe5b906000526020600020015484828151811062001c1a57fe5b602090810291909101015260010162001bec565b505050919050565b600e546001600160a01b031681565b6000546001600160a01b0316331462001c5d57600080fd5b600455565b6001546001600160a01b031681565b600e546001600160a01b0316331462001c8957600080fd5b6000858152600b602052604090206001815460ff16600481111562001caa57fe5b1462001cb557600080fd5b600185600481111562001cc457fe5b141562001cd057600080fd5b604080516101408101909152815462001f3591908390829060ff16600481111562001cf757fe5b600481111562001d0357fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001d5857602002820191906000526020600020905b81548152602001906001019080831162001d43575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001db257602002820191906000526020600020905b81548152602001906001019080831162001d9d575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801562001e765780601f1062001e4a5761010080835404028352916020019162001e76565b820191906000526020600020905b81548152906001019060200180831162001e5857829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815293820193929183018282801562001f0e5780601f1062001ee25761010080835404028352916020019162001f0e565b820191906000526020600020905b81548152906001019060200180831162001ef057829003601f168201915b50505050508152602001600882015481526020016009820154815250508686868662002855565b1562001f4c5762001f4686620028ad565b620021ae565b6040805161014081019091528154620021ae91908390829060ff16600481111562001f7357fe5b600481111562001f7f57fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fd457602002820191906000526020600020905b81548152602001906001019080831162001fbf575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200202e57602002820191906000526020600020905b81548152602001906001019080831162002019575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020f25780601f10620020c657610100808354040283529160200191620020f2565b820191906000526020600020905b815481529060010190602001808311620020d457829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200218a5780601f106200215e576101008083540402835291602001916200218a565b820191906000526020600020905b8154815290600101906020018083116200216c57829003601f168201915b50505050508152602001600882015481526020016009820154815250508362002963565b6000868152600b60205260409020805486919060ff19166001836004811115620021d457fe5b0217905550505050505050565b6000546001600160a01b03163314620021f957600080fd5b600e80546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b8451811015620022935762002288620022808683815181106200227157fe5b6020026020010151866200158f565b83906200298c565b915060010162002252565b509392505050565b620022a5620031ab565b600a548210620022c157620022b96200299f565b905062000e64565b600a8281548110620022cf57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200235357602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162002334575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200241857602002820191906000526020600020905b81548152602001906001019080831162002403575b5050509183525050600a919091015460ff161515602090910152905062000e64565b600a5490565b600080546001600160a01b031633146200245957600080fd5b6001600160a01b0382166200246d57600080fd5b60005462002485906001600160a01b03168362002988565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024b462003157565b6000600c8381548110620024c457fe5b90600052602060002001549050620024dc81620011f7565b9150915091565b600c8181548110620024f457600080fd5b600091825260209091200154905081565b60008262002516575060006200156c565b828202828482816200252457fe5b04146200253057600080fd5b9392505050565b6000808284816200254457fe5b04949350505050565b6000828211156200255d57600080fd5b50900390565b600080805b600c5481101562000f7a576000600c82815481106200258357fe5b906000526020600020015490506200259b81620025b2565b15620025a8576001909201915b5060010162002568565b600080620025c08362001b8c565b90506000805b825181101562002293576000838281518110620025df57fe5b602002602001015190508060001415801562002603575062002601816200106d565b155b156200261457600192505062002293565b50600101620025c6565b604080516001808252818301909252606091602080830190803683370190505090506200264d84848462002a15565b816000815181106200265b57fe5b6020026020010181815250509392505050565b6040805160018082528183019092526060916020808301908036833701905050905090565b6000888152600b602052604081205460ff166004811115620026b157fe5b14620026d15760405162461bcd60e51b8152600401620015bb9062003a1b565b60005b8751811015620027145788600d60008a8481518110620026f057fe5b602090810291909101810151825281019190915260400160002055600101620026d4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027769391909101918a019062003219565b506000888152600b6020908152604090912087516200279e9260029092019189019062003219565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027db9260069092019185019062003269565b506000888152600b602090815260409091208251620028039260079092019184019062003269565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200284398979695949392919062003c73565b60405180910390a15050505050505050565b6000600382148160028760048111156200286b57fe5b60808a015160a08b0151929091141592508714159086141583806200288d5750825b80620028965750815b806200289f5750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200290857602002820191906000526020600020905b815481526020019060010190808311620028f3575b5050505050905060005b81518110156200295e5760008282815181106200292b57fe5b60200260200101519050806000141562002946575062002955565b6200295381600062002add565b505b60010162002912565b505050565b6200298882602001516000815181106200297957fe5b60200260200101518262002c06565b5050565b6000828201838110156200253057600080fd5b620029a9620031ab565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002ad5939192909183018282801562002aa95780601f1062002a7d5761010080835404028352916020019162002aa9565b820191906000526020600020905b81548152906001019060200180831162002a8b57829003601f168201915b5050505050848462002acf8860016002811062002ac257fe5b6020020151895162002c21565b62002d2b565b949350505050565b6000600a838154811062002aed57fe5b90600052602060002090600b02019050600081600101838154811062002b0f57fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002b8e57600080fd5b505afa15801562002ba3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002bcd91908101906200350c565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b7f565b600062002c138262002d56565b90506200295e838262002add565b6060600062002c308462002d87565b9050600062002c3f8462002d87565b905081810162002c5e8162000c916802a802f8630a2400008662002505565b925062002c7a8162000c916802a802f8630a2400008562002505565b9150670de0b6b3a764000083101562002c9257600080fd5b670de0b6b3a764000082101562002ca857600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a76400008460008151811062002ce057fe5b602002602001018181525050828460018151811062002cfb57fe5b602002602001018181525050818460028151811062002d1657fe5b60200260200101818152505050505092915050565b60008062002d3b86868662002de9565b905062002d4c338285600162002e6e565b9695505050505050565b6000816001141562002d6b5750600262000e64565b816002141562002d7e5750600162000e64565b50600062000e64565b60008082121562002dc657600082900362002dbd62002da88260646200298c565b62000c91836802a802f8630a24000062002505565b91505062000e64565b620022b962002dd78360646200298c565b690109a12906aff61000009062002537565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e01579050509050838160008151811062002e2857fe5b6020026020010181905250818160018151811062002e4257fe5b6020026020010181905250828160028151811062002e5c57fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002e9d873062003062565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f3d93928501929190910190620032eb565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162002fbf91600984019160209091019062003219565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec90620030129083908790879062003bfc565b60405180910390a1811562002ad5577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f888160405162003052919062003b76565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff811180156200308157600080fd5b50604051908082528060200260200182016040528015620030ac578160200160208202803683370190505b50905060005b828110156200314e57858181518110620030c857fe5b6020026020010151868281518110620030dd57fe5b602002602001015186604051620030f49062003343565b6200310293929190620039d9565b604051809103906000f0801580156200311f573d6000803e3d6000fd5b508282815181106200312d57fe5b6001600160a01b0390921660209283029190910190910152600101620030b2565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b82805482825590600052602060002090810192821562003257579160200282015b82811115620032575782518255916020019190600101906200323a565b506200326592915062003351565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032a1576000855562003257565b82601f10620032bc57805160ff191683800117855562003257565b82800160010185558215620032575791820182811115620032575782518255916020019190600101906200323a565b82805482825590600052602060002090810192821562003257579160200282015b828111156200325757825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200330c565b6111f38062003da083390190565b5b8082111562003265576000815560010162003352565b80356001600160a01b038116811462000e6457600080fd5b600082601f83011262003391578081fd5b8135620033a8620033a28262003d37565b62003d12565b818152846020838601011115620033bd578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215620033e9578081fd5b620025308262003368565b6000806040838503121562003407578081fd5b620034128362003368565b91506020830135620034248162003d8d565b809150509250929050565b6000806040838503121562003442578182fd5b823567ffffffffffffffff808211156200345a578384fd5b818501915085601f8301126200346e578384fd5b81356020828211156200347d57fe5b80820292506200348f81840162003d12565b8281528181019085830185870184018b1015620034aa578889fd5b8896505b84871015620034ce578035835260019690960195918301918301620034ae565b509650620034e0905087820162003368565b9450505050509250929050565b600060208284031215620034ff578081fd5b8151620025308162003d8d565b6000602082840312156200351e578081fd5b815167ffffffffffffffff81111562003535578182fd5b8201601f8101841362003546578182fd5b805162003557620033a28262003d37565b8181528560208385010111156200356c578384fd5b6200357f82602083016020860162003d5a565b95945050505050565b6000602082840312156200359a578081fd5b5035919050565b600060208284031215620035b3578081fd5b5051919050565b60008060408385031215620035cd578182fd5b82359150620035df6020840162003368565b90509250929050565b600080600080600060a0868803121562003600578081fd5b8535945060208601356005811062003616578182fd5b94979496505050506040830135926060810135926080909101359150565b600080600080600080600061010080898b03121562003651578586fd5b883597506020808a013567ffffffffffffffff8082111562003671578889fd5b6200367f8d838e0162003380565b995060408c0135985060608c01359150808211156200369c578586fd5b620036aa8d838e0162003380565b975060808c0135965060a08c013595508c60df8d0112620036c9578485fd5b6040519150604082018281108282111715620036e157fe5b604052508060c08c01848d018e1015620036f9578586fd5b8594505b60028510156200371e578035825260019490940193908301908301620036fd565b505080935050505092959891949750929550565b60008060006060848603121562003747578081fd5b8335925060208401359150620037606040850162003368565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b83811015620037b05781516001600160a01b03168752958201959082019060010162003789565b509495945050505050565b6000815180845260208085019450808401835b83811015620037b057815187529582019590820190600101620037ce565b15159052565b60058110620037fd57fe5b9052565b600081518084526200381b81602086016020860162003d5a565b601f01601f19169290920160200192915050565b600061014062003841848451620037f2565b60208301518160208601526200385a82860182620037bb565b91505060408301518482036040860152620038768282620037bb565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c0860152620038b0828262003801565b91505060e083015184820360e0860152620038cc828262003801565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060208252620025306020830184620037bb565b901515815260200190565b600061010062003970838c620037f2565b896020840152886040840152876060840152806080840152620039968184018862003801565b905082810360a0840152620039ac818762003801565b60c0840195909552505060e001529695505050505050565b60006020825262002530602083018462003801565b600060608252620039ee606083018662003801565b828103602084015262003a02818662003801565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a8260208301845162003769565b602083015161016080604085015262003aa061018085018362003776565b9150604085015162003ab6606086018262003769565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b1c8483620037bb565b93508087015191505062003b3382860182620037ec565b5090949350505050565b6000602082526200253060208301846200382f565b60006040825262003b6760408301856200382f565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262002d4c608083018462003801565b600088825260018060a01b038816602083015286604083015260e0606083015262003bdd60e083018762003801565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5a57607f1988870301845262003c4786835162003801565b9550928401929084019060010162003c28565b5050505050828103604084015262002d4c8185620037bb565b60006101008a835280602084015262003c8f8184018b620037bb565b9050828103604084015262003ca5818a620037bb565b905087606084015286608084015282810360a084015262003cc7818762003801565b905082810360c084015262003cdd818662003801565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2f57fe5b604052919050565b600067ffffffffffffffff82111562003d4c57fe5b50601f01601f191660200190565b60005b8381101562003d7757818101518382015260200162003d5d565b8381111562003d87576000848401525b50505050565b801515811462003d9c57600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a264697066735822122027590c2bfea9ba8c944f7c4df67942d3cfc147534a780651e8f3b40af2f4b31864736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { @@ -1432,8 +1432,8 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(OwnedERC20)25830)dyn_storage": { - "base": "t_contract(OwnedERC20)25830", + "t_array(t_contract(OwnedERC20)25781)dyn_storage": { + "base": "t_contract(OwnedERC20)25781", "encoding": "dynamic_array", "label": "contract OwnedERC20[]", "numberOfBytes": "32" @@ -1471,7 +1471,7 @@ "label": "contract IERC20Full", "numberOfBytes": "20" }, - "t_contract(OwnedERC20)25830": { + "t_contract(OwnedERC20)25781": { "encoding": "inplace", "label": "contract OwnedERC20", "numberOfBytes": "20" @@ -1530,7 +1530,7 @@ "label": "shareTokens", "offset": 0, "slot": "1", - "type": "t_array(t_contract(OwnedERC20)25830)dyn_storage" + "type": "t_array(t_contract(OwnedERC20)25781)dyn_storage" }, { "astId": 15185, @@ -1538,7 +1538,7 @@ "label": "winner", "offset": 0, "slot": "2", - "type": "t_contract(OwnedERC20)25830" + "type": "t_contract(OwnedERC20)25781" }, { "astId": 15187, diff --git a/packages/smart/deployments/maticMumbai/NBAFetcher.json b/packages/smart/deployments/maticMumbai/NBAFetcher.json index 0fcd53b2d..628fc82c6 100644 --- a/packages/smart/deployments/maticMumbai/NBAFetcher.json +++ b/packages/smart/deployments/maticMumbai/NBAFetcher.json @@ -1,5 +1,5 @@ { - "address": "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", + "address": "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", "abi": [ { "inputs": [], @@ -431,21 +431,21 @@ "type": "function" } ], - "transactionHash": "0x8ad9a6acb03f5a5d60f465cc21ea7a468ef79e0866d3cf8e449d6b7f800652c4", + "transactionHash": "0xf049db506239dab48962bdb10c6be6454b0cbbb7cb2c058b8a71c3a58e3e5b73", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0x1FC98ecB4DbA35822A7efbdE238BB58FFb0f36BE", - "transactionIndex": 0, + "contractAddress": "0xe5708a8D1980dB451e9d8059BD20D1BEb6A0a688", + "transactionIndex": 1, "gasUsed": "1995332", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000000000000000000000000000000000000000000000800000000000000000080100000000000000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000024000000000000000000001000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x361f04e2f3efe5fa29f41e8d76e6d8ef2d4cdb945f13a002201e5fe086a4e28a", - "transactionHash": "0x8ad9a6acb03f5a5d60f465cc21ea7a468ef79e0866d3cf8e449d6b7f800652c4", + "blockHash": "0xf1831ff1b38ec02e06ff214f61474d014e0172e48d7d5ac0e5318194e59501d4", + "transactionHash": "0xf049db506239dab48962bdb10c6be6454b0cbbb7cb2c058b8a71c3a58e3e5b73", "logs": [ { - "transactionIndex": 0, - "blockNumber": 19809243, - "transactionHash": "0x8ad9a6acb03f5a5d60f465cc21ea7a468ef79e0866d3cf8e449d6b7f800652c4", + "transactionIndex": 1, + "blockNumber": 20388731, + "transactionHash": "0xf049db506239dab48962bdb10c6be6454b0cbbb7cb2c058b8a71c3a58e3e5b73", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -453,21 +453,21 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x0000000000000000000000000000000000000000000000000015443b4d34f8000000000000000000000000000000000000000000000000036525d20ba997af290000000000000000000000000000000000000000000000000176b82f65c26e0000000000000000000000000000000000000000000000000365108dd05c62b729000000000000000000000000000000000000000000000000018bfc6ab2f76600", - "logIndex": 0, - "blockHash": "0x361f04e2f3efe5fa29f41e8d76e6d8ef2d4cdb945f13a002201e5fe086a4e28a" + "data": "0x00000000000000000000000000000000000000000000000000198513f63f9000000000000000000000000000000000000000000000000003344ff8d0994664740000000000000000000000000000000000000000000000000446ce447c0472f0000000000000000000000000000000000000000000000003343673bca306d47400000000000000000000000000000000000000000000000004605358724402f0", + "logIndex": 2, + "blockHash": "0xf1831ff1b38ec02e06ff214f61474d014e0172e48d7d5ac0e5318194e59501d4" } ], - "blockNumber": 19809243, - "cumulativeGasUsed": "1995332", + "blockNumber": 20388731, + "cumulativeGasUsed": "2016332", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct SportsFetcher.DynamicEventBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestEventIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct SportsFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct SportsFetcher.StaticEventBundle[]\",\"name\":\"_eventBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestEventIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/Fetcher.sol\":\"NBAFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n HasSpreadMarket(Spread, InvalidName)\\n HasOverUnderMarket(OverUnder, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x0d4c083d82b07c94a03831f3b79e9cdc1f6016c3532199b03cbd7d81b7d2a757\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50604051806040016040528060038152602001624e424160e81b8152506040518060400160405280600381526020016215109160ea1b81525081600090805190602001906200006292919062000081565b5080516200007890600190602084019062000081565b5050506200012d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000b9576000855562000104565b82601f10620000d457805160ff191683800117855562000104565b8280016001018555821562000104579182015b8281111562000104578251825591602001919060010190620000e7565b506200011292915062000116565b5090565b5b8082111562000112576000815560010162000117565b61223f806200013d6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f3660046118c1565b6100bc565b60405161007494939291906120b9565b60405180910390f35b6100856100f5565b60405161007491906120a6565b610085610183565b6100ad6100a836600461191b565b6101dd565b60405161007493929190611f47565b6100c4611447565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b610206611447565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c61145f565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114c4565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac6565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f4565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611bcb565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611bcb565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611bcb565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611bcb565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f79190611992565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611992565b610c44565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611bcb565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b03166371be2e4a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611bcb565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051637ab1e4cd60e11b81526000199094019360009081906001600160a01b038b169063f563c99a90610864908990600401612178565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611b87565b915091506108c6828b610d51565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b61091161145f565b604051630ce3d6d360e31b81526000906001600160a01b0387169063671eb69890610940908690600401612178565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611b55565b905060008160200151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611540565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886602001518581518110610a1257fe5b6020026020010151610dad565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b5083835281516101008401906004811115610a5557fe5b90816004811115610a6257fe5b905250602083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100810151610120808401919091520151610140820152949350505050565b610ace6114c4565b604051630ce3d6d360e31b81526000906001600160a01b0386169063671eb69890610afd908690600401612178565b60006040518083038186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b519190810190611b55565b905060008160200151516001600160401b0381118015610b7057600080fd5b50604051908082528060200260200182016040528015610baa57816020015b610b97611598565b815260200190600190039081610b8f5790505b50905060005b8151811015610bfa57610bdb878785602001518481518110610bce57fe5b6020026020010151610f1f565b828281518110610be757fe5b6020908102919091010152600101610bb0565b5083835260408301819052815160208401906004811115610c1757fe5b90816004811115610c2457fe5b905250506101008101516060830152610120015160808201529392505050565b610c4c6115c4565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8f57600080fd5b505afa158015610ca3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ccb91908101906119ae565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0c57600080fd5b505afa158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d449190611be3565b60ff166040820152919050565b6000805b836020015151811015610da157600084602001518281518110610d7457fe5b60200260200101519050610d888482610fe3565b15610d9857600192505050610da7565b50600101610d55565b50600090505b92915050565b610db5611540565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610de4908690600401612178565b60006040518083038186803b158015610dfc57600080fd5b505afa158015610e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3891908101906119e0565b6001600160a01b0387168352602083018490529050610e58868685611105565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610e8f9088908a908890600401612069565b60a06040518083038186803b158015610ea757600080fd5b505afa158015610ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edf9190611ae9565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f27611598565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f56908690600401612178565b60006040518083038186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610faa91908101906119e0565b6001600160a01b0380871684526020840185905260408201511660608401529050610fd6858585611105565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016110129190612178565b60006040518083038186803b15801561102a57600080fd5b505afa15801561103e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106691908101906119e0565b60408101519091506001600160a01b0316611085576001915050610da7565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc9190611bcb565b11949350505050565b61110d6115ee565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea29061113e908890879060040161208d565b60206040518083038186803b15801561115657600080fd5b505afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190611992565b90506001600160a01b0381166111a45750611440565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111e757600080fd5b505afa1580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121f9190611bcb565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990611252908890879060040161208d565b60206040518083038186803b15801561126a57600080fd5b505afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190611bcb565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112d5908890879060040161208d565b60006040518083038186803b1580156112ed57600080fd5b505afa158015611301573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113299190810190611960565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd9061135e908890879060040161208d565b60006040518083038186803b15801561137657600080fd5b505afa15801561138a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113b29190810190611960565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113e5908890879060040161208d565b60006040518083038186803b1580156113fd57600080fd5b505afa158015611411573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114399190810190611960565b6060830152505b9392505050565b604051806020016040528061145a6114f4565b905290565b6040518061016001604052806000815260200160608152602001606081526020016000815260200160008152602001600081526020016060815260200160608152602001600060048111156114b057fe5b815260200160008152602001600081525090565b6040805160a081019091526000808252602082019081526020016060815260200160008152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115336115c4565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115606115ee565b815260200161156d61162d565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115b76115ee565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8051611669816121f1565b919050565b600082601f83011261167e578081fd5b8151602061169361168e836121a4565b612181565b82815281810190858301838502870184018810156116af578586fd5b855b858110156116d65781516116c4816121f1565b845292840192908401906001016116b1565b5090979650505050505050565b600082601f8301126116f3578081fd5b8151602061170361168e836121a4565b828152818101908583018385028701840188101561171f578586fd5b855b858110156116d657815184529284019290840190600101611721565b8051801515811461166957600080fd5b80516005811061166957600080fd5b600082601f83011261176c578081fd5b81516001600160401b0381111561177f57fe5b611792601f8201601f1916602001612181565b8181528460208386010111156117a6578283fd5b6117b78260208301602087016121c1565b949350505050565b60006101408083850312156117d2578182fd5b6117db81612181565b9150506117e78261174d565b815260208201516001600160401b038082111561180357600080fd5b61180f858386016116e3565b6020840152604084015191508082111561182857600080fd5b611834858386016116e3565b6040840152606084015160608401526080840151608084015260a084015160a084015260c084015191508082111561186b57600080fd5b6118778583860161175c565b60c084015260e084015191508082111561189057600080fd5b5061189d8482850161175c565b60e08301525061010080830151818301525061012080830151818301525092915050565b600080600080600060a086880312156118d8578081fd5b85356118e3816121f1565b945060208601356118f3816121f1565b93506040860135611903816121f1565b94979396509394606081013594506080013592915050565b60008060008060808587031215611930578182fd5b843561193b816121f1565b9350602085013561194b816121f1565b93969395505050506040820135916060013590565b600060208284031215611971578081fd5b81516001600160401b03811115611986578182fd5b6117b7848285016116e3565b6000602082840312156119a3578081fd5b8151611440816121f1565b6000602082840312156119bf578081fd5b81516001600160401b038111156119d4578182fd5b6117b78482850161175c565b6000602082840312156119f1578081fd5b81516001600160401b0380821115611a07578283fd5b8184019150610160808387031215611a1d578384fd5b611a2681612181565b9050611a318361165e565b8152602083015182811115611a44578485fd5b611a508782860161166e565b602083015250611a626040840161165e565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611ab8578586fd5b611ac4888287016116e3565b8284015250506101409150611ada82840161173d565b91810191909152949350505050565b600060a08284031215611afa578081fd5b60405160a081018181106001600160401b0382111715611b1657fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611b496080840161173d565b60808201529392505050565b600060208284031215611b66578081fd5b81516001600160401b03811115611b7b578182fd5b6117b7848285016117bf565b60008060408385031215611b99578182fd5b82516001600160401b03811115611bae578283fd5b611bba858286016117bf565b925050602083015190509250929050565b600060208284031215611bdc578081fd5b5051919050565b600060208284031215611bf4578081fd5b815160ff81168114611440578182fd5b6000815180845260208085019450808401835b83811015611c3c5781516001600160a01b031687529582019590820190600101611c17565b509495945050505050565b6000815180845260208085019450808401835b83811015611c3c57815187529582019590820190600101611c5a565b6000815180845260208085018081965082840281019150828601855b85811015611d6e578284038952815161016081518652868201518188880152611cbd82880182611d7b565b91505060408083015187830382890152611cd78382611c47565b925050506060808301518188015250608080830151818801525060a080830151818801525060c08083015187830382890152611d138382611e6e565b9250505060e08083015187830382890152611d2e8382611e6e565b9250505061010080830151611d4582890182611e60565b505061012082810151908701526101409182015191909501529784019790840190600101611c92565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611d6e5782840389528151610180611db4868351611e53565b86820151878701526040808301518282890152611dd383890182611e9a565b92505050606080830151611de982890182611f15565b50506080820151868203610100880152611e038282611c04565b91505060a082015161012087015260c0820151611e24610140880182611e53565b5060e08201519150858103610160870152611e3f8183611c47565b9a87019a9550505090840190600101611d97565b6001600160a01b03169052565b60058110611e6a57fe5b9052565b60008151808452611e868160208601602086016121c1565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c06020850152611ec160c0850182611c47565b905060408301518482036040860152611eda8282611c47565b91505060608301518482036060860152611ef48282611c47565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561204f57607f19888403018552815160a084018151855287820151611f9989870182611e60565b50604082015160a0604087015281815180845260c08801915060c08b820289010193508a830192508b5b818110156120265760bf19898603018352835160018060a01b038082511687528d8201518e8801526040820151608060408901526120046080890182611e9a565b606093840151909216979092019690965250928b0192918b0191600101611fc3565b505050506060828101519086015260809182015191909401529385019390850190600101611f6e565b505092850196909652506040909201929092529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114406020830184611e6e565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526121386101e0860182611e6e565b905060408201516101c086015260c083015161016086015284810360208601526121628189611c76565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561219c57fe5b604052919050565b60006001600160401b038211156121b757fe5b5060209081020190565b60005b838110156121dc5781810151838201526020016121c4565b838111156121eb576000848401525b50505050565b6001600160a01b038116811461220657600080fd5b5056fea2646970667358221220c30e437a3fd111c6921835582ceb26a71a75ea7e2f03666cfa75d96d6d5bc4ac64736f6c63430007060033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f3660046118c1565b6100bc565b60405161007494939291906120b9565b60405180910390f35b6100856100f5565b60405161007491906120a6565b610085610183565b6100ad6100a836600461191b565b6101dd565b60405161007493929190611f47565b6100c4611447565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b610206611447565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c61145f565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114c4565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac6565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f4565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611bcb565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611bcb565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611bcb565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611bcb565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f79190611992565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611992565b610c44565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611bcb565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b03166371be2e4a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611bcb565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051637ab1e4cd60e11b81526000199094019360009081906001600160a01b038b169063f563c99a90610864908990600401612178565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611b87565b915091506108c6828b610d51565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b61091161145f565b604051630ce3d6d360e31b81526000906001600160a01b0387169063671eb69890610940908690600401612178565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611b55565b905060008160200151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611540565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886602001518581518110610a1257fe5b6020026020010151610dad565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b5083835281516101008401906004811115610a5557fe5b90816004811115610a6257fe5b905250602083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100810151610120808401919091520151610140820152949350505050565b610ace6114c4565b604051630ce3d6d360e31b81526000906001600160a01b0386169063671eb69890610afd908690600401612178565b60006040518083038186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b519190810190611b55565b905060008160200151516001600160401b0381118015610b7057600080fd5b50604051908082528060200260200182016040528015610baa57816020015b610b97611598565b815260200190600190039081610b8f5790505b50905060005b8151811015610bfa57610bdb878785602001518481518110610bce57fe5b6020026020010151610f1f565b828281518110610be757fe5b6020908102919091010152600101610bb0565b5083835260408301819052815160208401906004811115610c1757fe5b90816004811115610c2457fe5b905250506101008101516060830152610120015160808201529392505050565b610c4c6115c4565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8f57600080fd5b505afa158015610ca3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ccb91908101906119ae565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0c57600080fd5b505afa158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d449190611be3565b60ff166040820152919050565b6000805b836020015151811015610da157600084602001518281518110610d7457fe5b60200260200101519050610d888482610fe3565b15610d9857600192505050610da7565b50600101610d55565b50600090505b92915050565b610db5611540565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610de4908690600401612178565b60006040518083038186803b158015610dfc57600080fd5b505afa158015610e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3891908101906119e0565b6001600160a01b0387168352602083018490529050610e58868685611105565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610e8f9088908a908890600401612069565b60a06040518083038186803b158015610ea757600080fd5b505afa158015610ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edf9190611ae9565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f27611598565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f56908690600401612178565b60006040518083038186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610faa91908101906119e0565b6001600160a01b0380871684526020840185905260408201511660608401529050610fd6858585611105565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016110129190612178565b60006040518083038186803b15801561102a57600080fd5b505afa15801561103e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106691908101906119e0565b60408101519091506001600160a01b0316611085576001915050610da7565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc9190611bcb565b11949350505050565b61110d6115ee565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea29061113e908890879060040161208d565b60206040518083038186803b15801561115657600080fd5b505afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190611992565b90506001600160a01b0381166111a45750611440565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111e757600080fd5b505afa1580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121f9190611bcb565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990611252908890879060040161208d565b60206040518083038186803b15801561126a57600080fd5b505afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190611bcb565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112d5908890879060040161208d565b60006040518083038186803b1580156112ed57600080fd5b505afa158015611301573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113299190810190611960565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd9061135e908890879060040161208d565b60006040518083038186803b15801561137657600080fd5b505afa15801561138a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113b29190810190611960565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113e5908890879060040161208d565b60006040518083038186803b1580156113fd57600080fd5b505afa158015611411573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114399190810190611960565b6060830152505b9392505050565b604051806020016040528061145a6114f4565b905290565b6040518061016001604052806000815260200160608152602001606081526020016000815260200160008152602001600081526020016060815260200160608152602001600060048111156114b057fe5b815260200160008152602001600081525090565b6040805160a081019091526000808252602082019081526020016060815260200160008152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115336115c4565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115606115ee565b815260200161156d61162d565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115b76115ee565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8051611669816121f1565b919050565b600082601f83011261167e578081fd5b8151602061169361168e836121a4565b612181565b82815281810190858301838502870184018810156116af578586fd5b855b858110156116d65781516116c4816121f1565b845292840192908401906001016116b1565b5090979650505050505050565b600082601f8301126116f3578081fd5b8151602061170361168e836121a4565b828152818101908583018385028701840188101561171f578586fd5b855b858110156116d657815184529284019290840190600101611721565b8051801515811461166957600080fd5b80516005811061166957600080fd5b600082601f83011261176c578081fd5b81516001600160401b0381111561177f57fe5b611792601f8201601f1916602001612181565b8181528460208386010111156117a6578283fd5b6117b78260208301602087016121c1565b949350505050565b60006101408083850312156117d2578182fd5b6117db81612181565b9150506117e78261174d565b815260208201516001600160401b038082111561180357600080fd5b61180f858386016116e3565b6020840152604084015191508082111561182857600080fd5b611834858386016116e3565b6040840152606084015160608401526080840151608084015260a084015160a084015260c084015191508082111561186b57600080fd5b6118778583860161175c565b60c084015260e084015191508082111561189057600080fd5b5061189d8482850161175c565b60e08301525061010080830151818301525061012080830151818301525092915050565b600080600080600060a086880312156118d8578081fd5b85356118e3816121f1565b945060208601356118f3816121f1565b93506040860135611903816121f1565b94979396509394606081013594506080013592915050565b60008060008060808587031215611930578182fd5b843561193b816121f1565b9350602085013561194b816121f1565b93969395505050506040820135916060013590565b600060208284031215611971578081fd5b81516001600160401b03811115611986578182fd5b6117b7848285016116e3565b6000602082840312156119a3578081fd5b8151611440816121f1565b6000602082840312156119bf578081fd5b81516001600160401b038111156119d4578182fd5b6117b78482850161175c565b6000602082840312156119f1578081fd5b81516001600160401b0380821115611a07578283fd5b8184019150610160808387031215611a1d578384fd5b611a2681612181565b9050611a318361165e565b8152602083015182811115611a44578485fd5b611a508782860161166e565b602083015250611a626040840161165e565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611ab8578586fd5b611ac4888287016116e3565b8284015250506101409150611ada82840161173d565b91810191909152949350505050565b600060a08284031215611afa578081fd5b60405160a081018181106001600160401b0382111715611b1657fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611b496080840161173d565b60808201529392505050565b600060208284031215611b66578081fd5b81516001600160401b03811115611b7b578182fd5b6117b7848285016117bf565b60008060408385031215611b99578182fd5b82516001600160401b03811115611bae578283fd5b611bba858286016117bf565b925050602083015190509250929050565b600060208284031215611bdc578081fd5b5051919050565b600060208284031215611bf4578081fd5b815160ff81168114611440578182fd5b6000815180845260208085019450808401835b83811015611c3c5781516001600160a01b031687529582019590820190600101611c17565b509495945050505050565b6000815180845260208085019450808401835b83811015611c3c57815187529582019590820190600101611c5a565b6000815180845260208085018081965082840281019150828601855b85811015611d6e578284038952815161016081518652868201518188880152611cbd82880182611d7b565b91505060408083015187830382890152611cd78382611c47565b925050506060808301518188015250608080830151818801525060a080830151818801525060c08083015187830382890152611d138382611e6e565b9250505060e08083015187830382890152611d2e8382611e6e565b9250505061010080830151611d4582890182611e60565b505061012082810151908701526101409182015191909501529784019790840190600101611c92565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611d6e5782840389528151610180611db4868351611e53565b86820151878701526040808301518282890152611dd383890182611e9a565b92505050606080830151611de982890182611f15565b50506080820151868203610100880152611e038282611c04565b91505060a082015161012087015260c0820151611e24610140880182611e53565b5060e08201519150858103610160870152611e3f8183611c47565b9a87019a9550505090840190600101611d97565b6001600160a01b03169052565b60058110611e6a57fe5b9052565b60008151808452611e868160208601602086016121c1565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c06020850152611ec160c0850182611c47565b905060408301518482036040860152611eda8282611c47565b91505060608301518482036060860152611ef48282611c47565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561204f57607f19888403018552815160a084018151855287820151611f9989870182611e60565b50604082015160a0604087015281815180845260c08801915060c08b820289010193508a830192508b5b818110156120265760bf19898603018352835160018060a01b038082511687528d8201518e8801526040820151608060408901526120046080890182611e9a565b606093840151909216979092019690965250928b0192918b0191600101611fc3565b505050506060828101519086015260809182015191909401529385019390850190600101611f6e565b505092850196909652506040909201929092529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114406020830184611e6e565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526121386101e0860182611e6e565b905060408201516101c086015260c083015161016086015284810360208601526121628189611c76565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561219c57fe5b604052919050565b60006001600160401b038211156121b757fe5b5060209081020190565b60005b838110156121dc5781810151838201526020016121c4565b838111156121eb576000848401525b50505050565b6001600160a01b038116811461220657600080fd5b5056fea2646970667358221220c30e437a3fd111c6921835582ceb26a71a75ea7e2f03666cfa75d96d6d5bc4ac64736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchDynamic\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"}],\"internalType\":\"struct Fetcher.DynamicMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct SportsFetcher.DynamicEventBundle[]\",\"name\":\"_bundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestEventIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_marketFactory\",\"type\":\"address\"},{\"internalType\":\"contract AMMFactory\",\"name\":\"_ammFactory\",\"type\":\"address\"},{\"internalType\":\"contract MasterChef\",\"name\":\"_masterChef\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_offset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_total\",\"type\":\"uint256\"}],\"name\":\"fetchInitial\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"feePot\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"symbol\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"decimals\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.CollateralBundle\",\"name\":\"collateral\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"marketCount\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.MarketFactoryBundle\",\"name\":\"super\",\"type\":\"tuple\"}],\"internalType\":\"struct SportsFetcher.SpecificMarketFactoryBundle\",\"name\":\"_marketFactoryBundle\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"contract AbstractMarketFactoryV3\",\"name\":\"factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"marketId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"tokenRatios\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"balances\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"weights\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalSupply\",\"type\":\"uint256\"}],\"internalType\":\"struct Fetcher.PoolBundle\",\"name\":\"pool\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"beginTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"endTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"earlyDepositEndTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"totalRewardsAccrued\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"created\",\"type\":\"bool\"}],\"internalType\":\"struct MasterChef.PoolStatusInfo\",\"name\":\"rewards\",\"type\":\"tuple\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"internalType\":\"struct Fetcher.StaticMarketBundle[]\",\"name\":\"markets\",\"type\":\"tuple[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct SportsFetcher.StaticEventBundle[]\",\"name\":\"_eventBundles\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_lowestEventIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketType\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/Fetcher.sol\":\"NBAFetcher\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0x62c8752bb170233359e653c61d491d6a79fe1d7d7281377c5ac4e9c03ce811ea\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0x549c5343ad9f7e3f38aa4c4761854403502574bbc15b822db2ce892ff9b79da7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc77dd6233a82c7c6e3dc49da8f3456baa00ecd3ea4dfa9222002a9aebf155dcd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf89f005a3d98f7768cdee2583707db0ac725cf567d455751af32ee68132f3db3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping (bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) { // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n return set._values[index];\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n}\\n\",\"keccak256\":\"0x9a2c1eebb65250f0e11882237038600f22a62376f0547db4acc0dfe0a3d8d34f\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BFactory.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is disstributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\\n\\nimport \\\"./BPool.sol\\\";\\n\\ncontract BFactory is BBronze {\\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\\n\\n event LOG_BLABS(address indexed caller, address indexed blabs);\\n\\n mapping(address => bool) private _isBPool;\\n\\n function isBPool(address b) external view returns (bool) {\\n return _isBPool[b];\\n }\\n\\n function newBPool() external returns (BPool) {\\n BPool bpool = new BPool();\\n _isBPool[address(bpool)] = true;\\n emit LOG_NEW_POOL(msg.sender, address(bpool));\\n bpool.setController(msg.sender);\\n return bpool;\\n }\\n\\n address private _blabs;\\n\\n constructor() {\\n _blabs = msg.sender;\\n }\\n\\n function getBLabs() external view returns (address) {\\n return _blabs;\\n }\\n\\n function setBLabs(address b) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n emit LOG_BLABS(msg.sender, b);\\n _blabs = b;\\n }\\n\\n function collect(BPool pool) external {\\n require(msg.sender == _blabs, \\\"ERR_NOT_BLABS\\\");\\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\\n bool xfer = pool.transfer(_blabs, collected);\\n require(xfer, \\\"ERR_ERC20_FAILED\\\");\\n }\\n}\\n\",\"keccak256\":\"0x43f179d1bc0b4f3da5c93def0636bb9cb04766dea6e3658740357b54cc79d02a\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByFiat.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _whoWon\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _whoWon);\\n }\\n\\n sportsEvents[_eventId].status = _eventStatus;\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\\n}\\n\",\"keccak256\":\"0xf2d069d1eab6d3131d5e51d73284beb8f788ccd26337d18470ff722cdd0e265e\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/rewards/MasterChef.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\npragma abicoder v2;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/EnumerableSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\" as OpenZeppelinOwnable;\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../turbo/AMMFactory.sol\\\";\\n\\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\\n using SafeMath for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public constant BONE = 10**18;\\n\\n // The percentage of the rewards period that early deposit bonus will payout.\\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\\n\\n // Info of each user.\\n struct UserInfo {\\n uint256 amount; // How many LP tokens the user has provided.\\n uint256 rewardDebt; // Reward debt. See explanation below.\\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\\n //\\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\\n // entitled to a user but is pending to be distributed is:\\n //\\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\\n //\\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\\n // 2. User receives the pending reward sent to his/her address.\\n // 3. User's `amount` gets updated.\\n // 4. User's `rewardDebt` gets updated.\\n }\\n // Info of each user that deposits LP tokens.\\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\\n\\n // Info of each pool.\\n struct PoolInfo {\\n IERC20 lpToken; // Address of LP token contract.\\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\\n }\\n // Info of each pool.\\n PoolInfo[] public poolInfo;\\n\\n // This is a snapshot of the current state of a market.\\n struct PoolStatusInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 totalRewardsAccrued;\\n bool created;\\n }\\n\\n struct PendingRewardInfo {\\n uint256 beginTimestamp;\\n uint256 endTimestamp;\\n uint256 earlyDepositEndTimestamp;\\n uint256 accruedStandardRewards;\\n uint256 accruedEarlyDepositBonusRewards;\\n uint256 pendingEarlyDepositBonusRewards;\\n bool created;\\n }\\n\\n struct MarketFactoryInfo {\\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\\n }\\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\\n\\n struct RewardPoolLookupInfo {\\n uint256 pid;\\n bool created;\\n }\\n\\n // AMMFactory => MarketFactory => MarketId\\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\\n\\n // The REWARD TOKEN!\\n IERC20 private rewardsToken;\\n\\n mapping(address => bool) private approvedAMMFactories;\\n\\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\\n event TrustMarketFactory(\\n address indexed MarketFactory,\\n uint256 OriginEarlyDepositBonusRewards,\\n uint256 OriginrewardsPeriods,\\n uint256 OriginRewardsPerPeriod,\\n uint256 EarlyDepositBonusRewards,\\n uint256 rewardsPeriods,\\n uint256 RewardsPerPeriod\\n );\\n\\n event PoolCreated(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed ammFactory,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n\\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\\n\\n constructor(IERC20 _rewardsToken) {\\n rewardsToken = _rewardsToken;\\n }\\n\\n function trustAMMFactory(address _ammFactory) public onlyOwner {\\n approvedAMMFactories[_ammFactory] = true;\\n }\\n\\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\\n delete approvedAMMFactories[_ammFactory];\\n }\\n\\n // This method can also be used to update rewards\\n function addRewards(\\n address _marketFactory,\\n uint256 _rewardsPerMarket,\\n uint256 _rewardDaysPerMarket,\\n uint256 _earlyDepositBonusRewards\\n ) public onlyOwner {\\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\\n rewardsPeriods: _rewardDaysPerMarket,\\n rewardsPerPeriod: _rewardsPerMarket,\\n earlyDepositBonusRewards: _earlyDepositBonusRewards\\n });\\n\\n emit TrustMarketFactory(\\n _marketFactory,\\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\\n _oldMarketFactoryInfo.rewardsPeriods,\\n _oldMarketFactoryInfo.rewardsPerPeriod,\\n _earlyDepositBonusRewards,\\n _rewardDaysPerMarket,\\n _rewardsPerMarket\\n );\\n }\\n\\n function poolLength() external view returns (uint256) {\\n return poolInfo.length;\\n }\\n\\n // Add a new lp to the pool. Can only be called by the owner.\\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\\n // An _endTimestamp of zero means the rewards start immediately.\\n function add(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) public onlyOwner returns (uint256 _nextPID) {\\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\\n }\\n\\n function addInternal(\\n address _ammFactory,\\n address _marketFactory,\\n uint256 _marketId,\\n IERC20 _lpToken,\\n uint256 _endTimestamp\\n ) internal returns (uint256 _nextPID) {\\n require(\\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\\n \\\"Reward pool has already been created.\\\"\\n );\\n\\n require(approvedAMMFactories[address(_ammFactory)], \\\"AMMFactory must be approved to create pool\\\");\\n\\n _nextPID = poolInfo.length;\\n\\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\\n\\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\\n\\n // Need to figure out the beginning/end of the reward period.\\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\\n uint256 _beginTimestamp = block.timestamp;\\n\\n // Add one hour buffer for LPs to withdraw before event start.\\n if (_endTimestamp != 0) {\\n _endTimestamp = _endTimestamp - 1 hours;\\n }\\n\\n if (_endTimestamp == 0) {\\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\\n } else if (block.timestamp >= _endTimestamp) {\\n // reward period already over.\\n _beginTimestamp = _endTimestamp;\\n }\\n poolInfo.push(\\n PoolInfo({\\n accRewardsPerShare: 0,\\n beginTimestamp: _beginTimestamp,\\n endTimestamp: _endTimestamp,\\n totalEarlyDepositBonusRewardShares: 0,\\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\\n (_endTimestamp - _beginTimestamp),\\n lpToken: _lpToken,\\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\\n lastRewardTimestamp: _beginTimestamp\\n })\\n );\\n }\\n\\n // Return number of seconds elapsed in terms of BONEs.\\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _fromTimestamp = block.timestamp;\\n\\n if (\\n // Rewards have not started yet.\\n _pool.beginTimestamp > _fromTimestamp ||\\n // Not sure how this happens but it is accounted for in the original master chef contract.\\n _pool.lastRewardTimestamp > _fromTimestamp ||\\n // No rewards to be distributed\\n _pool.rewardsPerSecond == 0\\n ) {\\n return 0;\\n }\\n\\n // Rewards are over for this pool. No more rewards have accrued.\\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\\n return 0;\\n }\\n\\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\\n }\\n\\n function getPoolTokenBalance(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\\n } else {\\n return 0;\\n }\\n }\\n\\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\\n return userInfo[_pid][_user].amount;\\n }\\n\\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n return _pool.endTimestamp;\\n }\\n\\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\\n PoolInfo storage _pool = poolInfo[_pid];\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n }\\n\\n function getPoolLPTokenTotalSupply(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (uint256) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\\n }\\n\\n function getPoolLPToken(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (IERC20) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\\n }\\n\\n function getPoolInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId\\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n // This cannot revert as it will be used in a multicall.\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n _poolStatusInfo.totalRewardsAccrued =\\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\\n _pool.rewardsPerSecond;\\n _poolStatusInfo.created = true;\\n }\\n }\\n\\n // View function to see pending REWARDs on frontend.\\n function getUserPendingRewardInfo(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _userAddress\\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n if (_rewardPoolLookupInfo.created) {\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\\n\\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\\n\\n _pendingRewardInfo.created = true;\\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\\n\\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\\n .earlyDepositBonusRewards\\n .mul(_user.amount)\\n .div(_pool.totalEarlyDepositBonusRewardShares);\\n }\\n }\\n\\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\\n }\\n\\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\\n _user.rewardDebt\\n );\\n }\\n }\\n\\n // Update reward variables for all pools. Be careful of gas spending!\\n function massUpdatePools() public {\\n uint256 length = poolInfo.length;\\n for (uint256 pid = 0; pid < length; ++pid) {\\n updatePool(pid);\\n }\\n }\\n\\n // Update reward variables of the given pool to be up-to-date.\\n function updatePool(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n if (block.timestamp <= pool.lastRewardTimestamp) {\\n return;\\n }\\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\\n if (lpSupply == 0) {\\n pool.lastRewardTimestamp = block.timestamp;\\n return;\\n }\\n uint256 multiplier = getTimeElapsed(_pid);\\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\\n pool.lastRewardTimestamp = block.timestamp;\\n }\\n\\n // Deposit LP tokens to MasterChef for REWARD allocation.\\n // Assumes the staked tokens are already on contract.\\n function depositInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n\\n updatePool(_pid);\\n\\n if (_user.amount > 0) {\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n safeRewardsTransfer(_userAddress, pending);\\n }\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n\\n // If the user was an early deposit, remove user amount from the pool.\\n // Even if the pools reward period has elapsed. They must withdraw first.\\n if (\\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n // Still in the early deposit bonus period.\\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\\n }\\n\\n _user.amount = _user.amount.add(_amount);\\n\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n emit Deposit(_userAddress, _pid, _amount);\\n }\\n\\n function depositByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n deposit(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function deposit(uint256 _pid, uint256 _amount) public {\\n depositInternal(msg.sender, _pid, _amount);\\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\\n }\\n\\n // Withdraw LP tokens from MasterChef.\\n // Assumes caller is handling distribution of LP tokens.\\n function withdrawInternal(\\n address _userAddress,\\n uint256 _pid,\\n uint256 _amount,\\n address _tokenRecipientAddress\\n ) internal {\\n PoolInfo storage _pool = poolInfo[_pid];\\n UserInfo storage _user = userInfo[_pid][_userAddress];\\n require(_user.amount >= _amount, \\\"withdraw: not good\\\");\\n\\n updatePool(_pid);\\n\\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\\n uint256 _bonusrewardsPeriodsEndTimestamp =\\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\\n\\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\\n if (\\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\\n ) {\\n uint256 _rewardsToUser =\\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\\n safeRewardsTransfer(_userAddress, _rewardsToUser);\\n }\\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\\n // Still in the early deposit bonus period.\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\\n } else if (\\n // If the user was an early deposit, remove user amount from the pool.\\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\\n ) {\\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\\n }\\n\\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\\n\\n safeRewardsTransfer(_tokenRecipientAddress, pending);\\n _user.amount = _user.amount.sub(_amount);\\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\\n _user.lastActionTimestamp = block.timestamp;\\n\\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\\n }\\n\\n function withdrawByMarket(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _amount\\n ) public {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdraw(_rewardPoolLookupInfo.pid, _amount);\\n }\\n\\n function withdraw(uint256 _pid, uint256 _amount) public {\\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\\n }\\n\\n function createPool(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\\n\\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\\n\\n uint256 _nextPID =\\n addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n _lpToken,\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n\\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokensIn),\\n _balances\\n );\\n\\n return _lpTokensIn;\\n }\\n\\n function addLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n uint256 _pid = _rewardPoolLookupInfo.pid;\\n\\n // If not created should attempt to create it.\\n if (!_rewardPoolLookupInfo.created) {\\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\\n require(_bPool != BPool(0), \\\"Pool not created.\\\");\\n\\n _pid = addInternal(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n IERC20(address(_bPool)),\\n _marketFactory.getRewardEndTime(_marketId)\\n );\\n }\\n\\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\\n\\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\\n _marketFactory,\\n _marketId,\\n _collateralIn,\\n _minLPTokensOut,\\n address(this)\\n );\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n for (uint256 i = 0; i < _balances.length; i++) {\\n if (_balances[i] > 0) {\\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AMMFactory _ammFactory,\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\\n\\n require(_rewardPoolLookupInfo.created, \\\"Reward pool has not been created.\\\");\\n\\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\\n\\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\\n\\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\\n\\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\\n _marketFactory,\\n _marketId,\\n _lpTokensIn,\\n _minCollateralOut,\\n _collateralRecipient\\n );\\n\\n emit LiquidityChanged(\\n address(_ammFactory),\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function withdrawRewards(uint256 _amount) external onlyOwner {\\n rewardsToken.transfer(msg.sender, _amount);\\n }\\n\\n // Withdraw without caring about rewards. EMERGENCY ONLY.\\n function emergencyWithdraw(uint256 _pid) public {\\n PoolInfo storage pool = poolInfo[_pid];\\n UserInfo storage user = userInfo[_pid][msg.sender];\\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\\n user.amount = 0;\\n user.rewardDebt = 0;\\n user.lastActionTimestamp = 0;\\n }\\n\\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\\n if (_amount > _rewardsBal) {\\n rewardsToken.transfer(_to, _rewardsBal);\\n } else {\\n rewardsToken.transfer(_to, _amount);\\n }\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x6330d89bb43513e0eac4ad7cbd0a39093750be8d981623897e2c266594a8072f\",\"license\":\"MIT\"},\"contracts/turbo/AMMFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma experimental ABIEncoderV2;\\n\\nimport \\\"../balancer/BFactory.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"../balancer/BNum.sol\\\";\\n\\ncontract AMMFactory is BNum {\\n using SafeMathUint256 for uint256;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\\n\\n BFactory public bFactory;\\n // MarketFactory => Market => BPool\\n mapping(address => mapping(uint256 => BPool)) public pools;\\n uint256 fee;\\n\\n event PoolCreated(\\n address pool,\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed creator,\\n address lpTokenRecipient\\n );\\n event LiquidityChanged(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n address recipient,\\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\\n int256 collateral,\\n int256 lpTokens,\\n uint256[] sharesReturned\\n );\\n event SharesSwapped(\\n address indexed marketFactory,\\n uint256 indexed marketId,\\n address indexed user,\\n uint256 outcome,\\n // from the perspective of the user. e.g. collateral is negative when buying\\n int256 collateral,\\n int256 shares,\\n uint256 price\\n );\\n\\n constructor(BFactory _bFactory, uint256 _fee) {\\n bFactory = _bFactory;\\n fee = _fee;\\n }\\n\\n function createPool(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _initialLiquidity,\\n address _lpTokenRecipient\\n ) public returns (uint256) {\\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \\\"Pool already created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\\n\\n // Comparing to sets because sets are normalized to 10e18.\\n require(_sets >= MIN_INITIAL_LIQUIDITY, \\\"Initial liquidity must be at least 100 collateral.\\\");\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n require(\\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\\n \\\"insufficient collateral allowance for initial liquidity\\\"\\n );\\n\\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Create pool\\n BPool _pool = bFactory.newBPool();\\n\\n // Add each outcome to the pool. Collateral is NOT added.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _token.approve(address(_pool), MAX_UINT);\\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\\n }\\n\\n // Set the swap fee.\\n _pool.setSwapFee(fee);\\n\\n // Finalize pool setup\\n _pool.finalize();\\n\\n pools[address(_marketFactory)][_marketId] = _pool;\\n\\n // Pass along LP tokens for initial liquidity\\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\\n\\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\\n _pool.transfer(address(0x0), (BONE / 1000));\\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\\n\\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _balances[i] = 0;\\n }\\n\\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_initialLiquidity),\\n int256(_lpTokenBalance),\\n _balances\\n );\\n\\n return _lpTokenBalance;\\n }\\n\\n function addLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _collateralIn,\\n uint256 _minLPTokensOut,\\n address _lpTokenRecipient\\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n // Turn collateral into shares\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n _collateral.approve(address(_marketFactory), MAX_UINT);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n // Find poolAmountOut\\n _poolAmountOut = MAX_UINT;\\n\\n {\\n uint256 _totalSupply = _pool.totalSupply();\\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _maxAmountsIn[i] = _sets;\\n\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\\n\\n // This is the result the following when solving for poolAmountOut:\\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n // uint256 tokenAmountIn = bmul(ratio, bal);\\n uint256 _tokenPoolAmountOut =\\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\\n\\n if (_tokenPoolAmountOut < _poolAmountOut) {\\n _poolAmountOut = _tokenPoolAmountOut;\\n }\\n }\\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\\n }\\n\\n require(_poolAmountOut >= _minLPTokensOut, \\\"Would not have received enough LP tokens\\\");\\n\\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\\n\\n // Transfer the remaining shares back to _lpTokenRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n _balances[i] = _token.balanceOf(address(this));\\n if (_balances[i] > 0) {\\n _token.transfer(_lpTokenRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _lpTokenRecipient,\\n -int256(_collateralIn),\\n int256(_poolAmountOut),\\n _balances\\n );\\n }\\n\\n function removeLiquidity(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _lpTokensIn,\\n uint256 _minCollateralOut,\\n address _collateralRecipient\\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\\n\\n uint256[] memory exitPoolEstimate;\\n {\\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\\n _pool.exitPool(_lpTokensIn, minAmountsOut);\\n }\\n\\n // Find the number of sets to sell.\\n uint256 _setsToSell = MAX_UINT;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\\n }\\n\\n // Must be a multiple of share factor.\\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n\\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\\n if (_resolved) {\\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\\n } else {\\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\\n }\\n require(_collateralOut > _minCollateralOut, \\\"Amount of collateral returned too low.\\\");\\n\\n // Transfer the remaining shares back to _collateralRecipient.\\n _balances = new uint256[](_market.shareTokens.length);\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\\n if (_balances[i] > 0) {\\n _token.transfer(_collateralRecipient, _balances[i]);\\n }\\n }\\n\\n emit LiquidityChanged(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _collateralRecipient,\\n int256(_collateralOut),\\n -int256(_lpTokensIn),\\n _balances\\n );\\n }\\n\\n function buy(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256 _collateralIn,\\n uint256 _minTokensOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n IERC20Full _collateral = _marketFactory.collateral();\\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\\n _marketFactory.mintShares(_marketId, _sets, address(this));\\n\\n uint256 _totalDesiredOutcome = _sets;\\n {\\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 _acquiredToken, ) =\\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\\n _totalDesiredOutcome += _acquiredToken;\\n }\\n require(_totalDesiredOutcome >= _minTokensOut, \\\"Slippage exceeded\\\");\\n\\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\\n }\\n\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n -int256(_collateralIn),\\n int256(_totalDesiredOutcome),\\n bdiv(_sets, _totalDesiredOutcome)\\n );\\n\\n return _totalDesiredOutcome;\\n }\\n\\n function sellForCollateral(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n uint256 _outcome,\\n uint256[] memory _shareTokensIn,\\n uint256 _minSetsOut\\n ) external returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n require(_pool != BPool(0), \\\"Pool needs to be created\\\");\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n uint256 _setsOut = MAX_UINT;\\n uint256 _totalUndesiredTokensIn = 0;\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n _totalUndesiredTokensIn += _shareTokensIn[i];\\n }\\n\\n {\\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\\n\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n if (i == _outcome) continue;\\n OwnedERC20 _token = _market.shareTokens[i];\\n (uint256 tokenAmountOut, ) =\\n _pool.swapExactAmountIn(\\n address(_market.shareTokens[_outcome]),\\n _shareTokensIn[i],\\n address(_token),\\n 0,\\n MAX_UINT\\n );\\n\\n //Ensure tokenAmountOut is a multiple of shareFactor.\\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\\n }\\n\\n require(_setsOut >= _minSetsOut, \\\"Minimum sets not available.\\\");\\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\\n }\\n\\n // Transfer undesired token balance back.\\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\\n OwnedERC20 _token = _market.shareTokens[i];\\n uint256 _balance = _token.balanceOf(address(this));\\n if (_balance > 0) {\\n _token.transfer(msg.sender, _balance);\\n }\\n }\\n\\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\\n emit SharesSwapped(\\n address(_marketFactory),\\n _marketId,\\n msg.sender,\\n _outcome,\\n int256(_collateralOut),\\n -int256(_totalUndesiredTokensIn),\\n bdiv(_setsOut, _totalUndesiredTokensIn)\\n );\\n\\n return _collateralOut;\\n }\\n\\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\\n // So the first outcome is 10**18 and all others are higher or lower.\\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n address _basisToken = address(_market.shareTokens[0]);\\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\\n _ratios[0] = 10**18;\\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\\n _ratios[i] = _price;\\n }\\n return _ratios;\\n }\\n\\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _balances = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _balances[i] = _pool.getBalance(_tokens[i]);\\n }\\n return _balances;\\n }\\n\\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n // Pool does not exist. Do not want to revert because multicall.\\n if (_pool == BPool(0)) {\\n return new uint256[](0);\\n }\\n\\n address[] memory _tokens = _pool.getCurrentTokens();\\n uint256[] memory _weights = new uint256[](_tokens.length);\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\\n }\\n return _weights;\\n }\\n\\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.getSwapFee();\\n }\\n\\n function getPoolTokenBalance(\\n AbstractMarketFactoryV3 _marketFactory,\\n uint256 _marketId,\\n address _user\\n ) external view returns (uint256) {\\n BPool _pool = pools[address(_marketFactory)][_marketId];\\n return _pool.balanceOf(_user);\\n }\\n\\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\\n return pools[address(_marketFactory)][_marketId];\\n }\\n}\\n\",\"keccak256\":\"0xc598cc27868135dc1783152fd9e923c5d321934c420e500fd57c726564a1f04d\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/CryptoCurrencyMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\n\\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\\n\\n enum Outcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n string constant Above = \\\"Above\\\";\\n string constant NotAbove = \\\"Not Above\\\";\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface feed;\\n uint256 value;\\n uint8 imprecision; // how many decimals to truncate\\n uint256 currentMarket; // 0 indicates no current market\\n }\\n Coin[] public coins;\\n\\n struct MarketDetails {\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionValue;\\n uint256 resolutionTime; // value at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.3.3\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // If _resolutionTime is 0 then do NOT create.\\n // If _roundId is 0 then do NOT resolve.\\n function pokeCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) public onlyLinkNode {\\n Coin storage _coin = coins[_coinIndex];\\n\\n // There's a market to resolve.\\n if (_roundId != 0 && _coin.currentMarket != 0) {\\n resolveMarket(_coin, _roundId);\\n }\\n\\n // Create a market\\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\\n createMarket(_coinIndex, _coin, _resolutionTime);\\n }\\n }\\n\\n function createMarket(\\n uint256 _coinIndex,\\n Coin storage _coin,\\n uint256 _resolutionTime\\n ) internal returns (uint256 _marketId) {\\n (, uint256 _newValue) = getLatestValue(_coin);\\n\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(Outcome.Above)] = Above;\\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\\n\\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\\n _coin.currentMarket = _marketId;\\n _coin.value = _newValue;\\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\\n }\\n\\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\\n\\n uint256 _winningOutcome;\\n if (_newValue > _coin.value) {\\n _winningOutcome = uint256(Outcome.Above);\\n } else {\\n _winningOutcome = uint256(Outcome.NotAbove);\\n }\\n\\n endMarket(_coin.currentMarket, _winningOutcome);\\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\\n _coin.currentMarket = 0;\\n _coin.value = 0;\\n }\\n\\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // Get value at a specific round, but fail if it isn't after a specific time.\\n function getSpecificValue(\\n Coin storage _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\\n require(_rawValue >= 0, \\\"Value from feed is negative\\\");\\n require(_updatedAt >= _resolutionTime, \\\"Value hasn't been updated yet\\\");\\n\\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n\\n _fullValue = uint256(_rawValue);\\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\\n }\\n\\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\\n internal\\n view\\n returns (uint256 _truncatedValue)\\n {\\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedValue = _fullValue / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedValue = _fullValue * (10**_greaten);\\n } else {\\n _truncatedValue = _fullValue;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedValue != _fullValue) {\\n _truncatedValue += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _feed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0x510151dc0a312273313e3b503db10c81a662056af82f35042d18ba4a906d454b\",\"license\":\"MIT\"},\"contracts/turbo/CryptoMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\\\";\\nimport \\\"../libraries/CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\nimport \\\"../libraries/ManagedByLink.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n event CoinAdded(uint256 indexed id, string name);\\n\\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\\n\\n struct Coin {\\n string name;\\n AggregatorV3Interface priceFeed;\\n uint256 price;\\n uint8 imprecision; // how many decimals to truncate\\n uint256[1] currentMarkets;\\n }\\n Coin[] public coins;\\n\\n enum MarketType {\\n PriceUpDown // 0\\n }\\n enum PriceUpDownOutcome {\\n Above, // 0\\n NotAbove // 1\\n }\\n struct MarketDetails {\\n MarketType marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionPrice;\\n uint256 resolutionTime; // price at given time; this is that time\\n }\\n // MarketId => MarketDetails\\n mapping(uint256 => MarketDetails) internal marketDetails;\\n\\n uint256 public nextResolutionTime;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n {\\n string memory _name = \\\"\\\";\\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\\n }\\n\\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\\n return marketDetails[_marketId];\\n }\\n\\n // NOTE: Trusts the owner not to add a coin twice.\\n // Returns the coin index.\\n function addCoin(\\n string calldata _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) external onlyOwner returns (uint256 _coinIndex) {\\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\\n _coinIndex = coins.length;\\n coins.push(_coin);\\n emit CoinAdded(_coinIndex, _name);\\n }\\n\\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\\n _coin = coins[_coinIndex];\\n }\\n\\n function getCoins() public view returns (Coin[] memory _coins) {\\n _coins = new Coin[](coins.length);\\n // Skip first coin because it's always the zeroed-out fake coin.\\n for (uint256 i = 1; i < coins.length; i++) {\\n _coins[i] = coins[i];\\n }\\n }\\n\\n // Iterates over all coins.\\n // If markets do not exist for coin, create them.\\n // Unless _nextResolutionTime is zero; then do not create new markets.\\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\\n // Else, error.\\n //\\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\\n // coins array.\\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\\n // If market creation was stopped then it can be started again.\\n // If market creation wasn't stopped then you must wait for market end time to resolve.\\n require(block.timestamp >= nextResolutionTime, \\\"Must wait for market resolution\\\");\\n require(_roundIds.length == coins.length, \\\"Must specify one roundId for each coin\\\");\\n\\n uint256 _resolutionTime = nextResolutionTime;\\n nextResolutionTime = _nextResolutionTime;\\n\\n uint256[] memory _prices = new uint256[](coins.length - 1);\\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\\n // Start at 1 to skip the fake Coin in the 0 index\\n for (uint256 i = 1; i < coins.length; i++) {\\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\\n }\\n\\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\\n }\\n\\n function createAndResolveMarketsForCoin(\\n uint256 _coinIndex,\\n uint256 _resolutionTime,\\n uint80 _roundId\\n ) internal returns (uint256 _price, uint256 _newMarketId) {\\n Coin memory _coin = coins[_coinIndex];\\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\\n\\n // resolve markets\\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\\n }\\n\\n // update price only AFTER resolution\\n coins[_coinIndex].price = _newPrice;\\n\\n // link node sets nextResolutionTime to zero to signify \\\"do not create markets after resolution\\\"\\n if (nextResolutionTime == 0) {\\n return (0, 0);\\n }\\n\\n // create markets\\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\\n\\n return (_newPrice, _newMarketId);\\n }\\n\\n function resolvePriceUpDownMarket(\\n Coin memory _coin,\\n uint256 _newPrice,\\n uint256 _fullPrice\\n ) internal {\\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\\n\\n uint256 _winningOutcome;\\n if (_newPrice > _coin.price) {\\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\\n } else {\\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\\n }\\n\\n endMarket(_marketId, _winningOutcome);\\n marketDetails[_marketId].resolutionPrice = _fullPrice;\\n }\\n\\n function createPriceUpDownMarket(\\n uint256 _coinIndex,\\n address _creator,\\n uint256 _newPrice\\n ) internal returns (uint256 _id) {\\n string[] memory _outcomes = new string[](2);\\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \\\"Above\\\";\\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \\\"Not Above\\\";\\n\\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\\n }\\n\\n // Returns the price based on a few factors.\\n // If _roundId is zero then it returns the latest price.\\n // Else, it returns the price for that round,\\n // but errors if that isn't the first round after the resolution time.\\n // The price is then altered to match the desired precision.\\n function getPrice(\\n Coin memory _coin,\\n uint80 _roundId,\\n uint256 _resolutionTime\\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\\n if (_roundId == 0) {\\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n _fullPrice = uint256(_rawPrice);\\n } else {\\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\\n require(_rawPrice >= 0, \\\"Price from feed is negative\\\");\\n require(updatedAt >= _resolutionTime, \\\"Price hasn't been updated yet\\\");\\n\\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\\n if (_resolutionTime != 0) {\\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\\n require(_previousRoundTime < _resolutionTime, \\\"Must use first round after resolution time\\\");\\n }\\n\\n _fullPrice = uint256(_rawPrice);\\n }\\n\\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\\n\\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\\n if (_precision > _coin.imprecision) {\\n uint8 _truncate = _precision - _coin.imprecision;\\n _truncatedPrice = _fullPrice / (10**_truncate);\\n } else if (_precision < _coin.imprecision) {\\n uint8 _greaten = _coin.imprecision - _precision;\\n _truncatedPrice = _fullPrice * (10**_greaten);\\n } else {\\n _truncatedPrice = _fullPrice;\\n }\\n\\n // Round up because that cleanly fits Above/Not-Above.\\n if (_truncatedPrice != _fullPrice) {\\n _truncatedPrice += 1;\\n }\\n }\\n\\n function makeCoin(\\n string memory _name,\\n AggregatorV3Interface _priceFeed,\\n uint8 _imprecision\\n ) internal pure returns (Coin memory _coin) {\\n uint256[1] memory _currentMarkets = [uint256(0)];\\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\\n }\\n\\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\\n // To find the previous roundId:\\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\\n // 2. decrement the phase-specific round\\n // 3. re-encode the phase and phase-specific round.\\n uint256 private constant PHASE_OFFSET = 64;\\n\\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\\n uint64 _roundId = uint64(_fullRoundId) - 1;\\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n return getMarketDetails(_marketId).resolutionTime;\\n }\\n}\\n\",\"keccak256\":\"0xddf34123d238c157ce6803baba98787b439d0d02c3cb36ba760ab2986a1e30dd\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/Fetcher.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"./MMAMarketFactoryV3.sol\\\";\\nimport \\\"./AMMFactory.sol\\\";\\nimport \\\"./CryptoMarketFactoryV3.sol\\\";\\nimport \\\"./NBAMarketFactoryV3.sol\\\";\\nimport \\\"../rewards/MasterChef.sol\\\";\\nimport \\\"./CryptoCurrencyMarketFactoryV3.sol\\\";\\n\\n// Helper contract for grabbing huge amounts of data without overloading multicall.\\nabstract contract Fetcher {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n struct CollateralBundle {\\n address addr;\\n string symbol;\\n uint256 decimals;\\n }\\n\\n struct MarketFactoryBundle {\\n uint256 shareFactor;\\n uint256 stakerFee;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n FeePot feePot;\\n CollateralBundle collateral;\\n uint256 marketCount;\\n }\\n\\n struct PoolBundle {\\n address addr;\\n uint256[] tokenRatios;\\n uint256[] balances;\\n uint256[] weights;\\n uint256 swapFee;\\n uint256 totalSupply;\\n }\\n\\n struct StaticMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n MasterChef.PoolStatusInfo rewards;\\n OwnedERC20[] shareTokens;\\n uint256 creationTimestamp;\\n OwnedERC20 winner;\\n uint256[] initialOdds;\\n }\\n\\n struct DynamicMarketBundle {\\n AbstractMarketFactoryV3 factory;\\n uint256 marketId;\\n PoolBundle pool;\\n OwnedERC20 winner;\\n }\\n\\n string public marketType;\\n string public version;\\n\\n constructor(string memory _type, string memory _version) {\\n marketType = _type;\\n version = _version;\\n }\\n\\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\\n _bundle.addr = address(_collateral);\\n _bundle.symbol = _collateral.symbol();\\n _bundle.decimals = _collateral.decimals();\\n }\\n\\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\\n internal\\n view\\n returns (MarketFactoryBundle memory _bundle)\\n {\\n _bundle.shareFactor = _marketFactory.shareFactor();\\n _bundle.stakerFee = _marketFactory.stakerFee();\\n _bundle.settlementFee = _marketFactory.settlementFee();\\n _bundle.protocolFee = _marketFactory.protocolFee();\\n _bundle.feePot = _marketFactory.feePot();\\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\\n _bundle.marketCount = _marketFactory.marketCount();\\n }\\n\\n function buildStaticMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (StaticMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\\n _bundle.shareTokens = _market.shareTokens;\\n _bundle.creationTimestamp = _market.creationTimestamp;\\n _bundle.winner = _market.winner;\\n _bundle.initialOdds = _market.initialOdds;\\n }\\n\\n function buildDynamicMarketBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (DynamicMarketBundle memory _bundle) {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n\\n _bundle.factory = _marketFactory;\\n _bundle.marketId = _marketId;\\n _bundle.winner = _market.winner;\\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\\n }\\n\\n function buildPoolBundle(\\n AbstractMarketFactoryV3 _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (PoolBundle memory _bundle) {\\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\\n if (_pool == BPool(address(0))) return _bundle;\\n\\n _bundle.addr = address(_pool);\\n _bundle.totalSupply = _pool.totalSupply();\\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\\n }\\n\\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\\n internal\\n view\\n returns (bool)\\n {\\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\\n if (_market.winner == OwnedERC20(address(0))) return true; // open\\n return _market.winner.totalSupply() > 0; // has winning shares\\n }\\n}\\n\\nabstract contract SportsFetcher is Fetcher {\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct StaticEventBundle {\\n uint256 id;\\n StaticMarketBundle[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n // Dynamics\\n Sport.SportsEventStatus status;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n struct DynamicEventBundle {\\n uint256 id;\\n Sport.SportsEventStatus status;\\n DynamicMarketBundle[] markets;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n StaticEventBundle[] memory _eventBundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _offset,\\n _total\\n );\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n DynamicEventBundle[] memory _bundles,\\n uint256 _lowestEventIndex,\\n uint256 _timestamp\\n )\\n {\\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\\n _timestamp = block.timestamp;\\n }\\n\\n function buildStaticEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new StaticEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\\n }\\n }\\n\\n function buildDynamicEventBundles(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\\n uint256[] memory _eventIds;\\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\\n\\n _total = _eventIds.length;\\n _bundles = new DynamicEventBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\\n }\\n }\\n\\n function buildStaticEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _eventId\\n ) internal view returns (StaticEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildStaticMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.status = _event.status;\\n _bundle.markets = _markets;\\n _bundle.lines = _event.lines;\\n _bundle.estimatedStartTime = _event.estimatedStartTime;\\n _bundle.homeTeamId = _event.homeTeamId;\\n _bundle.awayTeamId = _event.awayTeamId;\\n _bundle.homeTeamName = _event.homeTeamName;\\n _bundle.awayTeamName = _event.awayTeamName;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n function buildDynamicEventBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _eventId\\n ) internal view returns (DynamicEventBundle memory _bundle) {\\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\\n\\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\\n for (uint256 i = 0; i < _markets.length; i++) {\\n _markets[i] = buildDynamicMarketBundle(\\n AbstractMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _event.markets[i]\\n );\\n }\\n\\n _bundle.id = _eventId;\\n _bundle.markets = _markets;\\n _bundle.status = _event.status;\\n _bundle.homeScore = _event.homeScore;\\n _bundle.awayScore = _event.awayScore;\\n }\\n\\n // Starts from the end of the events list because newer events are more interesting.\\n // _offset is skipping all events, not just interesting events\\n function listOfInterestingEvents(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\\n _interestingEventIds = new uint256[](_total);\\n\\n uint256 _eventCount = Sport(_marketFactory).eventCount();\\n\\n // No events so return nothing. (needed to avoid integer underflow below)\\n if (_eventCount == 0) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _max = _eventCount;\\n\\n // No remaining events so return nothing. (needed to avoid integer underflow below)\\n if (_offset > _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n uint256 _collectedEvents = 0;\\n _eventIndex = _max - _offset;\\n while (true) {\\n if (_collectedEvents >= _total) break;\\n if (_eventIndex == 0) break;\\n\\n _eventIndex--; // starts out one too high, so this works\\n\\n (Sport.SportsEvent memory _event, uint256 _eventId) =\\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\\n\\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\\n _interestingEventIds[_collectedEvents] = _eventId;\\n _collectedEvents++;\\n }\\n }\\n\\n if (_total > _collectedEvents) {\\n assembly {\\n // shortens array\\n mstore(_interestingEventIds, _collectedEvents)\\n }\\n }\\n }\\n\\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\\n private\\n view\\n returns (bool)\\n {\\n for (uint256 i = 0; i < _event.markets.length; i++) {\\n uint256 _marketId = _event.markets[i];\\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\\n return true;\\n }\\n }\\n return false;\\n }\\n}\\n\\ncontract NBAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NBA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MLBFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MLB\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract MMAFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"MMA\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract NFLFetcher is SportsFetcher {\\n constructor() Fetcher(\\\"NFL\\\", \\\"TBD\\\") {}\\n}\\n\\ncontract CryptoFetcher is Fetcher {\\n constructor() Fetcher(\\\"Crypto\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint8 marketType;\\n uint256 coinIndex;\\n uint256 creationPrice;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionPrice;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionPrice;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.marketType = uint8(_details.marketType);\\n _bundle.creationPrice = _details.creationPrice;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoMarketFactoryV3.MarketDetails memory _details =\\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionPrice = _details.resolutionPrice;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\\ncontract CryptoCurrencyFetcher is Fetcher {\\n constructor() Fetcher(\\\"CryptoCurrency\\\", \\\"TBD\\\") {}\\n\\n struct SpecificMarketFactoryBundle {\\n MarketFactoryBundle super;\\n }\\n\\n struct SpecificStaticMarketBundle {\\n StaticMarketBundle super;\\n uint256 coinIndex;\\n uint256 creationValue;\\n uint256 resolutionTime;\\n // Dynamics\\n uint256 resolutionValue;\\n }\\n\\n struct SpecificDynamicMarketBundle {\\n DynamicMarketBundle super;\\n uint256 resolutionValue;\\n }\\n\\n function buildSpecificMarketFactoryBundle(address _marketFactory)\\n internal\\n view\\n returns (SpecificMarketFactoryBundle memory _bundle)\\n {\\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\\n }\\n\\n function buildSpecificStaticMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _marketId\\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildStaticMarketBundle(\\n CryptoCurrencyMarketFactoryV3(_marketFactory),\\n _ammFactory,\\n _masterChef,\\n _marketId\\n );\\n _bundle.creationValue = _details.creationValue;\\n _bundle.coinIndex = _details.coinIndex;\\n _bundle.resolutionValue = _details.resolutionValue;\\n _bundle.resolutionTime = _details.resolutionTime;\\n }\\n\\n function buildSpecificDynamicMarketBundle(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _marketId\\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\\n _bundle.resolutionValue = _details.resolutionValue;\\n }\\n\\n function fetchInitial(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n MasterChef _masterChef,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\\n SpecificStaticMarketBundle[] memory _marketBundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\\n\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _marketBundles = new SpecificStaticMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _marketBundles[i] = buildSpecificStaticMarketBundle(\\n _marketFactory,\\n _ammFactory,\\n _masterChef,\\n _marketIds[i]\\n );\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n function fetchDynamic(\\n address _marketFactory,\\n AMMFactory _ammFactory,\\n uint256 _offset,\\n uint256 _total\\n )\\n public\\n view\\n returns (\\n SpecificDynamicMarketBundle[] memory _bundles,\\n uint256 _lowestMarketIndex,\\n uint256 _timestamp\\n )\\n {\\n uint256[] memory _marketIds;\\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\\n\\n _total = _marketIds.length;\\n _bundles = new SpecificDynamicMarketBundle[](_total);\\n for (uint256 i; i < _total; i++) {\\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\\n }\\n\\n _timestamp = block.timestamp;\\n }\\n\\n // Starts from the end of the markets list because newer markets are more interesting.\\n // _offset is skipping all markets, not just interesting markets\\n function listOfInterestingMarkets(\\n address _marketFactory,\\n uint256 _offset,\\n uint256 _total\\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\\n _interestingMarketIds = new uint256[](_total);\\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\\n\\n // No markets so return nothing. (needed to prevent integer underflow below)\\n if (_max == 0 || _offset >= _max) {\\n return (new uint256[](0), 0);\\n }\\n\\n // Starts at the end, less offset.\\n // Stops before the 0th market since that market is always fake.\\n uint256 _collectedMarkets = 0;\\n _marketId = _max - _offset;\\n\\n while (true) {\\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\\n _interestingMarketIds[_collectedMarkets] = _marketId;\\n _collectedMarkets++;\\n }\\n\\n if (_collectedMarkets >= _total) break;\\n if (_marketId == 1) break; // skipping 0th market, which is fake\\n _marketId--; // starts out oone too high, so this works\\n }\\n\\n if (_total > _collectedMarkets) {\\n assembly {\\n // shortens array\\n mstore(_interestingMarketIds, _collectedMarkets)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xfb338ce56153b4bbd7a83ee32aefa173298965440a4f8e7f2f71c3f507afe590\",\"license\":\"MIT\"},\"contracts/turbo/MMAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/ResolveByFiat.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n string constant InvalidName = \\\"No Contest / Draw\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build1Line(),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](1);\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n }\\n\\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\\n }\\n\\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\\n if (WhoWonHome == _whoWon) {\\n return HeadToHeadHome;\\n } else if (WhoWonAway == _whoWon) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest; // shouldn't happen here\\n }\\n }\\n}\\n\",\"keccak256\":\"0x26571baca4c376974d4f6c007e1aeed3c5ccb85a8aca465b392c20e492d66066\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant Spread = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.5.0\\\")\\n ManagedByLink(_linkNode)\\n HasSpreadMarket(Spread, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n makeLine(_homeSpread),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\\n internal\\n returns (uint256[] memory _marketIds)\\n {\\n _marketIds = new uint256[](1);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n }\\n\\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\\n _line = build1Line();\\n _line[0] = addHalfPoint(_homeSpread);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x2187210295b55bd841518dc83cb592ef7365c4d7ba4f38895865e4d26ccefe35\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50604051806040016040528060038152602001624e424160e81b8152506040518060400160405280600381526020016215109160ea1b81525081600090805190602001906200006292919062000081565b5080516200007890600190602084019062000081565b5050506200012d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620000b9576000855562000104565b82601f10620000d457805160ff191683800117855562000104565b8280016001018555821562000104579182015b8281111562000104578251825591602001919060010190620000e7565b506200011292915062000116565b5090565b5b8082111562000112576000815560010162000117565b61223f806200013d6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f3660046118c1565b6100bc565b60405161007494939291906120b9565b60405180910390f35b6100856100f5565b60405161007491906120a6565b610085610183565b6100ad6100a836600461191b565b6101dd565b60405161007493929190611f47565b6100c4611447565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b610206611447565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c61145f565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114c4565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac6565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f4565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611bcb565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611bcb565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611bcb565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611bcb565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f79190611992565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611992565b610c44565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611bcb565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b03166371be2e4a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611bcb565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051637ab1e4cd60e11b81526000199094019360009081906001600160a01b038b169063f563c99a90610864908990600401612178565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611b87565b915091506108c6828b610d51565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b61091161145f565b604051630ce3d6d360e31b81526000906001600160a01b0387169063671eb69890610940908690600401612178565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611b55565b905060008160200151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611540565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886602001518581518110610a1257fe5b6020026020010151610dad565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b5083835281516101008401906004811115610a5557fe5b90816004811115610a6257fe5b905250602083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100810151610120808401919091520151610140820152949350505050565b610ace6114c4565b604051630ce3d6d360e31b81526000906001600160a01b0386169063671eb69890610afd908690600401612178565b60006040518083038186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b519190810190611b55565b905060008160200151516001600160401b0381118015610b7057600080fd5b50604051908082528060200260200182016040528015610baa57816020015b610b97611598565b815260200190600190039081610b8f5790505b50905060005b8151811015610bfa57610bdb878785602001518481518110610bce57fe5b6020026020010151610f1f565b828281518110610be757fe5b6020908102919091010152600101610bb0565b5083835260408301819052815160208401906004811115610c1757fe5b90816004811115610c2457fe5b905250506101008101516060830152610120015160808201529392505050565b610c4c6115c4565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8f57600080fd5b505afa158015610ca3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ccb91908101906119ae565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0c57600080fd5b505afa158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d449190611be3565b60ff166040820152919050565b6000805b836020015151811015610da157600084602001518281518110610d7457fe5b60200260200101519050610d888482610fe3565b15610d9857600192505050610da7565b50600101610d55565b50600090505b92915050565b610db5611540565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610de4908690600401612178565b60006040518083038186803b158015610dfc57600080fd5b505afa158015610e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3891908101906119e0565b6001600160a01b0387168352602083018490529050610e58868685611105565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610e8f9088908a908890600401612069565b60a06040518083038186803b158015610ea757600080fd5b505afa158015610ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edf9190611ae9565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f27611598565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f56908690600401612178565b60006040518083038186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610faa91908101906119e0565b6001600160a01b0380871684526020840185905260408201511660608401529050610fd6858585611105565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016110129190612178565b60006040518083038186803b15801561102a57600080fd5b505afa15801561103e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106691908101906119e0565b60408101519091506001600160a01b0316611085576001915050610da7565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc9190611bcb565b11949350505050565b61110d6115ee565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea29061113e908890879060040161208d565b60206040518083038186803b15801561115657600080fd5b505afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190611992565b90506001600160a01b0381166111a45750611440565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111e757600080fd5b505afa1580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121f9190611bcb565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990611252908890879060040161208d565b60206040518083038186803b15801561126a57600080fd5b505afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190611bcb565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112d5908890879060040161208d565b60006040518083038186803b1580156112ed57600080fd5b505afa158015611301573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113299190810190611960565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd9061135e908890879060040161208d565b60006040518083038186803b15801561137657600080fd5b505afa15801561138a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113b29190810190611960565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113e5908890879060040161208d565b60006040518083038186803b1580156113fd57600080fd5b505afa158015611411573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114399190810190611960565b6060830152505b9392505050565b604051806020016040528061145a6114f4565b905290565b6040518061016001604052806000815260200160608152602001606081526020016000815260200160008152602001600081526020016060815260200160608152602001600060048111156114b057fe5b815260200160008152602001600081525090565b6040805160a081019091526000808252602082019081526020016060815260200160008152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115336115c4565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115606115ee565b815260200161156d61162d565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115b76115ee565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8051611669816121f1565b919050565b600082601f83011261167e578081fd5b8151602061169361168e836121a4565b612181565b82815281810190858301838502870184018810156116af578586fd5b855b858110156116d65781516116c4816121f1565b845292840192908401906001016116b1565b5090979650505050505050565b600082601f8301126116f3578081fd5b8151602061170361168e836121a4565b828152818101908583018385028701840188101561171f578586fd5b855b858110156116d657815184529284019290840190600101611721565b8051801515811461166957600080fd5b80516005811061166957600080fd5b600082601f83011261176c578081fd5b81516001600160401b0381111561177f57fe5b611792601f8201601f1916602001612181565b8181528460208386010111156117a6578283fd5b6117b78260208301602087016121c1565b949350505050565b60006101408083850312156117d2578182fd5b6117db81612181565b9150506117e78261174d565b815260208201516001600160401b038082111561180357600080fd5b61180f858386016116e3565b6020840152604084015191508082111561182857600080fd5b611834858386016116e3565b6040840152606084015160608401526080840151608084015260a084015160a084015260c084015191508082111561186b57600080fd5b6118778583860161175c565b60c084015260e084015191508082111561189057600080fd5b5061189d8482850161175c565b60e08301525061010080830151818301525061012080830151818301525092915050565b600080600080600060a086880312156118d8578081fd5b85356118e3816121f1565b945060208601356118f3816121f1565b93506040860135611903816121f1565b94979396509394606081013594506080013592915050565b60008060008060808587031215611930578182fd5b843561193b816121f1565b9350602085013561194b816121f1565b93969395505050506040820135916060013590565b600060208284031215611971578081fd5b81516001600160401b03811115611986578182fd5b6117b7848285016116e3565b6000602082840312156119a3578081fd5b8151611440816121f1565b6000602082840312156119bf578081fd5b81516001600160401b038111156119d4578182fd5b6117b78482850161175c565b6000602082840312156119f1578081fd5b81516001600160401b0380821115611a07578283fd5b8184019150610160808387031215611a1d578384fd5b611a2681612181565b9050611a318361165e565b8152602083015182811115611a44578485fd5b611a508782860161166e565b602083015250611a626040840161165e565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611ab8578586fd5b611ac4888287016116e3565b8284015250506101409150611ada82840161173d565b91810191909152949350505050565b600060a08284031215611afa578081fd5b60405160a081018181106001600160401b0382111715611b1657fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611b496080840161173d565b60808201529392505050565b600060208284031215611b66578081fd5b81516001600160401b03811115611b7b578182fd5b6117b7848285016117bf565b60008060408385031215611b99578182fd5b82516001600160401b03811115611bae578283fd5b611bba858286016117bf565b925050602083015190509250929050565b600060208284031215611bdc578081fd5b5051919050565b600060208284031215611bf4578081fd5b815160ff81168114611440578182fd5b6000815180845260208085019450808401835b83811015611c3c5781516001600160a01b031687529582019590820190600101611c17565b509495945050505050565b6000815180845260208085019450808401835b83811015611c3c57815187529582019590820190600101611c5a565b6000815180845260208085018081965082840281019150828601855b85811015611d6e578284038952815161016081518652868201518188880152611cbd82880182611d7b565b91505060408083015187830382890152611cd78382611c47565b925050506060808301518188015250608080830151818801525060a080830151818801525060c08083015187830382890152611d138382611e6e565b9250505060e08083015187830382890152611d2e8382611e6e565b9250505061010080830151611d4582890182611e60565b505061012082810151908701526101409182015191909501529784019790840190600101611c92565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611d6e5782840389528151610180611db4868351611e53565b86820151878701526040808301518282890152611dd383890182611e9a565b92505050606080830151611de982890182611f15565b50506080820151868203610100880152611e038282611c04565b91505060a082015161012087015260c0820151611e24610140880182611e53565b5060e08201519150858103610160870152611e3f8183611c47565b9a87019a9550505090840190600101611d97565b6001600160a01b03169052565b60058110611e6a57fe5b9052565b60008151808452611e868160208601602086016121c1565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c06020850152611ec160c0850182611c47565b905060408301518482036040860152611eda8282611c47565b91505060608301518482036060860152611ef48282611c47565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561204f57607f19888403018552815160a084018151855287820151611f9989870182611e60565b50604082015160a0604087015281815180845260c08801915060c08b820289010193508a830192508b5b818110156120265760bf19898603018352835160018060a01b038082511687528d8201518e8801526040820151608060408901526120046080890182611e9a565b606093840151909216979092019690965250928b0192918b0191600101611fc3565b505050506060828101519086015260809182015191909401529385019390850190600101611f6e565b505092850196909652506040909201929092529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114406020830184611e6e565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526121386101e0860182611e6e565b905060408201516101c086015260c083015161016086015284810360208601526121628189611c76565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561219c57fe5b604052919050565b60006001600160401b038211156121b757fe5b5060209081020190565b60005b838110156121dc5781810151838201526020016121c4565b838111156121eb576000848401525b50505050565b6001600160a01b038116811461220657600080fd5b5056fea2646970667358221220e988a328ccfbd2ad4a5d934ba4240259d63503bc28dc2a2506b28c3d277222fe64736f6c63430007060033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806322254b88146100515780632dd489091461007d57806354fd4d501461009257806356d274911461009a575b600080fd5b61006461005f3660046118c1565b6100bc565b60405161007494939291906120b9565b60405180910390f35b6100856100f5565b60405161007491906120a6565b610085610183565b6100ad6100a836600461191b565b6101dd565b60405161007493929190611f47565b6100c4611447565b60606000806100d2896101fe565b93506100e18989898989610216565b949a90995093975042965092945050505050565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b820191906000526020600020905b81548152906001019060200180831161015e57829003601f168201915b505050505081565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561017b5780601f106101505761010080835404028352916020019161017b565b60606000806101ee878787876102d7565b9098909750429650945050505050565b610206611447565b61020f82610396565b8152919050565b606060006060610227888686610710565b8151955092509050836001600160401b038111801561024557600080fd5b5060405190808252806020026020018201604052801561027f57816020015b61026c61145f565b8152602001906001900390816102645790505b50925060005b848110156102cb576102ac89898985858151811061029f57fe5b6020026020010151610909565b8482815181106102b857fe5b6020908102919091010152600101610285565b50509550959350505050565b6060600060606102e8878686610710565b8151955092509050836001600160401b038111801561030657600080fd5b5060405190808252806020026020018201604052801561034057816020015b61032d6114c4565b8152602001906001900390816103255790505b50925060005b8481101561038b5761036c888884848151811061035f57fe5b6020026020010151610ac6565b84828151811061037857fe5b6020908102919091010152600101610346565b505094509492505050565b61039e6114f4565b816001600160a01b0316637641ab016040518163ffffffff1660e01b815260040160206040518083038186803b1580156103d757600080fd5b505afa1580156103eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040f9190611bcb565b816000018181525050816001600160a01b0316634b2d9ffc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561045157600080fd5b505afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190611bcb565b816020018181525050816001600160a01b0316637d1d7fb86040518163ffffffff1660e01b815260040160206040518083038186803b1580156104cb57600080fd5b505afa1580156104df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105039190611bcb565b816040018181525050816001600160a01b031663b0e21e8a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054557600080fd5b505afa158015610559573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061057d9190611bcb565b816060018181525050816001600160a01b0316634c9f66c76040518163ffffffff1660e01b815260040160206040518083038186803b1580156105bf57600080fd5b505afa1580156105d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f79190611992565b81608001906001600160a01b031690816001600160a01b03168152505061068d826001600160a01b031663d8dfeb456040518163ffffffff1660e01b815260040160206040518083038186803b15801561065057600080fd5b505afa158015610664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106889190611992565b610c44565b8160a00181905250816001600160a01b031663ec9790826040518163ffffffff1660e01b815260040160206040518083038186803b1580156106ce57600080fd5b505afa1580156106e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107069190611bcb565b60c0820152919050565b60606000826001600160401b038111801561072a57600080fd5b50604051908082528060200260200182016040528015610754578160200160208202803683370190505b5091506000856001600160a01b03166371be2e4a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561079257600080fd5b505afa1580156107a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107ca9190611bcb565b9050806107ea575050604080516000808252602082019092529150610901565b808086111561080e5750506040805160008082526020820190925292509050610901565b600086820393505b858110610822576108f1565b8361082c576108f1565b604051637ab1e4cd60e11b81526000199094019360009081906001600160a01b038b169063f563c99a90610864908990600401612178565b60006040518083038186803b15801561087c57600080fd5b505afa158015610890573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108b89190810190611b87565b915091506108c6828b610d51565b156108ea57808784815181106108d857fe5b60209081029190910101526001909201915b5050610816565b808611156108fd578085525b5050505b935093915050565b61091161145f565b604051630ce3d6d360e31b81526000906001600160a01b0387169063671eb69890610940908690600401612178565b60006040518083038186803b15801561095857600080fd5b505afa15801561096c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109949190810190611b55565b905060008160200151516001600160401b03811180156109b357600080fd5b506040519080825280602002602001820160405280156109ed57816020015b6109da611540565b8152602001906001900390816109d25790505b50905060005b8151811015610a3e57610a1f88888886602001518581518110610a1257fe5b6020026020010151610dad565b828281518110610a2b57fe5b60209081029190910101526001016109f3565b5083835281516101008401906004811115610a5557fe5b90816004811115610a6257fe5b905250602083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100810151610120808401919091520151610140820152949350505050565b610ace6114c4565b604051630ce3d6d360e31b81526000906001600160a01b0386169063671eb69890610afd908690600401612178565b60006040518083038186803b158015610b1557600080fd5b505afa158015610b29573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b519190810190611b55565b905060008160200151516001600160401b0381118015610b7057600080fd5b50604051908082528060200260200182016040528015610baa57816020015b610b97611598565b815260200190600190039081610b8f5790505b50905060005b8151811015610bfa57610bdb878785602001518481518110610bce57fe5b6020026020010151610f1f565b828281518110610be757fe5b6020908102919091010152600101610bb0565b5083835260408301819052815160208401906004811115610c1757fe5b90816004811115610c2457fe5b905250506101008101516060830152610120015160808201529392505050565b610c4c6115c4565b6001600160a01b038216808252604080516395d89b4160e01b815290516395d89b4191600480820192600092909190829003018186803b158015610c8f57600080fd5b505afa158015610ca3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ccb91908101906119ae565b8160200181905250816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015610d0c57600080fd5b505afa158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d449190611be3565b60ff166040820152919050565b6000805b836020015151811015610da157600084602001518281518110610d7457fe5b60200260200101519050610d888482610fe3565b15610d9857600192505050610da7565b50600101610d55565b50600090505b92915050565b610db5611540565b60405163eb44fdd360e01b81526000906001600160a01b0387169063eb44fdd390610de4908690600401612178565b60006040518083038186803b158015610dfc57600080fd5b505afa158015610e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e3891908101906119e0565b6001600160a01b0387168352602083018490529050610e58868685611105565b604080840191909152516327def0cb60e21b81526001600160a01b03851690639f7bc32c90610e8f9088908a908890600401612069565b60a06040518083038186803b158015610ea757600080fd5b505afa158015610ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610edf9190611ae9565b60608301526020810151608083015260e08082015160a084015260408201516001600160a01b031660c08401526101209091015190820152949350505050565b610f27611598565b60405163eb44fdd360e01b81526000906001600160a01b0386169063eb44fdd390610f56908690600401612178565b60006040518083038186803b158015610f6e57600080fd5b505afa158015610f82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610faa91908101906119e0565b6001600160a01b0380871684526020840185905260408201511660608401529050610fd6858585611105565b6040830152509392505050565b600080836001600160a01b031663eb44fdd3846040518263ffffffff1660e01b81526004016110129190612178565b60006040518083038186803b15801561102a57600080fd5b505afa15801561103e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106691908101906119e0565b60408101519091506001600160a01b0316611085576001915050610da7565b600081604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156110c457600080fd5b505afa1580156110d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110fc9190611bcb565b11949350505050565b61110d6115ee565b604051632dadcf5160e11b81526000906001600160a01b03851690635b5b9ea29061113e908890879060040161208d565b60206040518083038186803b15801561115657600080fd5b505afa15801561116a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118e9190611992565b90506001600160a01b0381166111a45750611440565b6001600160a01b038116808352604080516318160ddd60e01b815290516318160ddd91600480820192602092909190829003018186803b1580156111e757600080fd5b505afa1580156111fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121f9190611bcb565b60a083015260405163fa0de35960e01b81526001600160a01b0385169063fa0de35990611252908890879060040161208d565b60206040518083038186803b15801561126a57600080fd5b505afa15801561127e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112a29190611bcb565b608083015260405163d2364bf360e01b81526001600160a01b0385169063d2364bf3906112d5908890879060040161208d565b60006040518083038186803b1580156112ed57600080fd5b505afa158015611301573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113299190810190611960565b6040808401919091525163c7b4b6dd60e01b81526001600160a01b0385169063c7b4b6dd9061135e908890879060040161208d565b60006040518083038186803b15801561137657600080fd5b505afa15801561138a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113b29190810190611960565b602083015260405163d055da7160e01b81526001600160a01b0385169063d055da71906113e5908890879060040161208d565b60006040518083038186803b1580156113fd57600080fd5b505afa158015611411573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114399190810190611960565b6060830152505b9392505050565b604051806020016040528061145a6114f4565b905290565b6040518061016001604052806000815260200160608152602001606081526020016000815260200160008152602001600081526020016060815260200160608152602001600060048111156114b057fe5b815260200160008152602001600081525090565b6040805160a081019091526000808252602082019081526020016060815260200160008152602001600081525090565b6040518060e001604052806000815260200160008152602001600081526020016000815260200160006001600160a01b031681526020016115336115c4565b8152602001600081525090565b6040805161010081018252600080825260208201529081016115606115ee565b815260200161156d61162d565b8152602001606081526020016000815260200160006001600160a01b03168152602001606081525090565b60408051608081018252600080825260208201529081016115b76115ee565b8152600060209091015290565b604051806060016040528060006001600160a01b0316815260200160608152602001600081525090565b6040518060c0016040528060006001600160a01b0316815260200160608152602001606081526020016060815260200160008152602001600081525090565b6040518060a00160405280600081526020016000815260200160008152602001600081526020016000151581525090565b8051611669816121f1565b919050565b600082601f83011261167e578081fd5b8151602061169361168e836121a4565b612181565b82815281810190858301838502870184018810156116af578586fd5b855b858110156116d65781516116c4816121f1565b845292840192908401906001016116b1565b5090979650505050505050565b600082601f8301126116f3578081fd5b8151602061170361168e836121a4565b828152818101908583018385028701840188101561171f578586fd5b855b858110156116d657815184529284019290840190600101611721565b8051801515811461166957600080fd5b80516005811061166957600080fd5b600082601f83011261176c578081fd5b81516001600160401b0381111561177f57fe5b611792601f8201601f1916602001612181565b8181528460208386010111156117a6578283fd5b6117b78260208301602087016121c1565b949350505050565b60006101408083850312156117d2578182fd5b6117db81612181565b9150506117e78261174d565b815260208201516001600160401b038082111561180357600080fd5b61180f858386016116e3565b6020840152604084015191508082111561182857600080fd5b611834858386016116e3565b6040840152606084015160608401526080840151608084015260a084015160a084015260c084015191508082111561186b57600080fd5b6118778583860161175c565b60c084015260e084015191508082111561189057600080fd5b5061189d8482850161175c565b60e08301525061010080830151818301525061012080830151818301525092915050565b600080600080600060a086880312156118d8578081fd5b85356118e3816121f1565b945060208601356118f3816121f1565b93506040860135611903816121f1565b94979396509394606081013594506080013592915050565b60008060008060808587031215611930578182fd5b843561193b816121f1565b9350602085013561194b816121f1565b93969395505050506040820135916060013590565b600060208284031215611971578081fd5b81516001600160401b03811115611986578182fd5b6117b7848285016116e3565b6000602082840312156119a3578081fd5b8151611440816121f1565b6000602082840312156119bf578081fd5b81516001600160401b038111156119d4578182fd5b6117b78482850161175c565b6000602082840312156119f1578081fd5b81516001600160401b0380821115611a07578283fd5b8184019150610160808387031215611a1d578384fd5b611a2681612181565b9050611a318361165e565b8152602083015182811115611a44578485fd5b611a508782860161166e565b602083015250611a626040840161165e565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e08201526101008084015181830152506101208084015183811115611ab8578586fd5b611ac4888287016116e3565b8284015250506101409150611ada82840161173d565b91810191909152949350505050565b600060a08284031215611afa578081fd5b60405160a081018181106001600160401b0382111715611b1657fe5b806040525082518152602083015160208201526040830151604082015260608301516060820152611b496080840161173d565b60808201529392505050565b600060208284031215611b66578081fd5b81516001600160401b03811115611b7b578182fd5b6117b7848285016117bf565b60008060408385031215611b99578182fd5b82516001600160401b03811115611bae578283fd5b611bba858286016117bf565b925050602083015190509250929050565b600060208284031215611bdc578081fd5b5051919050565b600060208284031215611bf4578081fd5b815160ff81168114611440578182fd5b6000815180845260208085019450808401835b83811015611c3c5781516001600160a01b031687529582019590820190600101611c17565b509495945050505050565b6000815180845260208085019450808401835b83811015611c3c57815187529582019590820190600101611c5a565b6000815180845260208085018081965082840281019150828601855b85811015611d6e578284038952815161016081518652868201518188880152611cbd82880182611d7b565b91505060408083015187830382890152611cd78382611c47565b925050506060808301518188015250608080830151818801525060a080830151818801525060c08083015187830382890152611d138382611e6e565b9250505060e08083015187830382890152611d2e8382611e6e565b9250505061010080830151611d4582890182611e60565b505061012082810151908701526101409182015191909501529784019790840190600101611c92565b5091979650505050505050565b6000815180845260208085018081965082840281019150828601855b85811015611d6e5782840389528151610180611db4868351611e53565b86820151878701526040808301518282890152611dd383890182611e9a565b92505050606080830151611de982890182611f15565b50506080820151868203610100880152611e038282611c04565b91505060a082015161012087015260c0820151611e24610140880182611e53565b5060e08201519150858103610160870152611e3f8183611c47565b9a87019a9550505090840190600101611d97565b6001600160a01b03169052565b60058110611e6a57fe5b9052565b60008151808452611e868160208601602086016121c1565b601f01601f19169290920160200192915050565b600060018060a01b038251168352602082015160c06020850152611ec160c0850182611c47565b905060408301518482036040860152611eda8282611c47565b91505060608301518482036060860152611ef48282611c47565b9150506080830151608085015260a083015160a08501528091505092915050565b805182526020810151602083015260408101516040830152606081015160608301526080810151151560808301525050565b60006060820160608352808651808352608085019150602092506080838202860101838901855b8381101561204f57607f19888403018552815160a084018151855287820151611f9989870182611e60565b50604082015160a0604087015281815180845260c08801915060c08b820289010193508a830192508b5b818110156120265760bf19898603018352835160018060a01b038082511687528d8201518e8801526040820151608060408901526120046080890182611e9a565b606093840151909216979092019690965250928b0192918b0191600101611fc3565b505050506060828101519086015260809182015191909401529385019390850190600101611f6e565b505092850196909652506040909201929092529392505050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6000602082526114406020830184611e6e565b600060808252855160206080840152805160a0840152602081015160c0840152604081015160e08401526060810151610100840152608081015160018060a01b0380821661012086015260a0830151915060e06101408601528082511661018086015250602081015160606101a08601526121386101e0860182611e6e565b905060408201516101c086015260c083015161016086015284810360208601526121628189611c76565b6040860197909752505050506060015292915050565b90815260200190565b6040518181016001600160401b038111828210171561219c57fe5b604052919050565b60006001600160401b038211156121b757fe5b5060209081020190565b60005b838110156121dc5781810151838201526020016121c4565b838111156121eb576000848401525b50505050565b6001600160a01b038116811461220657600080fd5b5056fea2646970667358221220e988a328ccfbd2ad4a5d934ba4240259d63503bc28dc2a2506b28c3d277222fe64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/packages/smart/deployments/maticMumbai/NBAMarketFactoryV3.json b/packages/smart/deployments/maticMumbai/NBAMarketFactoryV3.json index 05f7c6482..d47246c73 100644 --- a/packages/smart/deployments/maticMumbai/NBAMarketFactoryV3.json +++ b/packages/smart/deployments/maticMumbai/NBAMarketFactoryV3.json @@ -1,5 +1,5 @@ { - "address": "0x9A45627C8479D8dA6F270067C5451BcdaC477Aa0", + "address": "0xedf8f21CD357Fb3B51dfc9bAc227a678344956CE", "abi": [ { "inputs": [ @@ -512,16 +512,6 @@ "internalType": "int256", "name": "_homeSpread", "type": "int256" - }, - { - "internalType": "int256", - "name": "_totalScore", - "type": "int256" - }, - { - "internalType": "int256[2]", - "name": "_moneylines", - "type": "int256[2]" } ], "name": "createEvent", @@ -1214,35 +1204,35 @@ "type": "function" } ], - "transactionHash": "0x3d0ef94bdce24a2a620a1ce2fdd1eddf5e6add34d589aed5376c3ae7fe0de2c4", + "transactionHash": "0xd40f771583f087c62c46a075de9c265179db5d695831e3121731d357fe3fab5d", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0x9A45627C8479D8dA6F270067C5451BcdaC477Aa0", + "contractAddress": "0xedf8f21CD357Fb3B51dfc9bAc227a678344956CE", "transactionIndex": 0, - "gasUsed": "5173526", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000080000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000010000000000000000000000000000000000000000080024000000000000000000001000000000100000000000000000000100000000000000010000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0xd77a27852a29538368553c32daadab8ec727e0bb93a3b244c7de6afbd07b98d3", - "transactionHash": "0x3d0ef94bdce24a2a620a1ce2fdd1eddf5e6add34d589aed5376c3ae7fe0de2c4", + "gasUsed": "4765082", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000020000000000000000000000000000000004080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000000000000000000000000000000100000000000000010000000000040000000000000000000000000000000080000000000100000", + "blockHash": "0x0dd778c8e03caa54ab1132ef560433c032ee8b08da925c2f1c74817d78c5d1d3", + "transactionHash": "0xd40f771583f087c62c46a075de9c265179db5d695831e3121731d357fe3fab5d", "logs": [ { "transactionIndex": 0, - "blockNumber": 19809863, - "transactionHash": "0x3d0ef94bdce24a2a620a1ce2fdd1eddf5e6add34d589aed5376c3ae7fe0de2c4", + "blockNumber": 20388710, + "transactionHash": "0xd40f771583f087c62c46a075de9c265179db5d695831e3121731d357fe3fab5d", "address": "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x0000000000000000000000009a45627c8479d8da6f270067c5451bcdac477aa0", + "0x000000000000000000000000edf8f21cd357fb3b51dfc9bac227a678344956ce", "0x00000000000000000000000059ddfe9961e050bda1ed9bf9ccd009948036dd76" ], "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "logIndex": 0, - "blockHash": "0xd77a27852a29538368553c32daadab8ec727e0bb93a3b244c7de6afbd07b98d3" + "blockHash": "0x0dd778c8e03caa54ab1132ef560433c032ee8b08da925c2f1c74817d78c5d1d3" }, { "transactionIndex": 0, - "blockNumber": 19809863, - "transactionHash": "0x3d0ef94bdce24a2a620a1ce2fdd1eddf5e6add34d589aed5376c3ae7fe0de2c4", + "blockNumber": 20388710, + "transactionHash": "0xd40f771583f087c62c46a075de9c265179db5d695831e3121731d357fe3fab5d", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -1250,13 +1240,13 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x000000000000000000000000000000000000000000000000003723e22a66140000000000000000000000000000000000000000000000000364d83ea361a0422900000000000000000000000000000000000000000000000001d0591ddd91fc0000000000000000000000000000000000000000000000000364a11ac1373a2e2900000000000000000000000000000000000000000000000002077d0007f81000", + "data": "0x0000000000000000000000000000000000000000000000000032c97353ce8c000000000000000000000000000000000000000000000000033573377775515a740000000000000000000000000000000000000000000000000262b21d1a1a38f000000000000000000000000000000000000000000000000335406e042182ce7400000000000000000000000000000000000000000000000002957b906de8c4f0", "logIndex": 1, - "blockHash": "0xd77a27852a29538368553c32daadab8ec727e0bb93a3b244c7de6afbd07b98d3" + "blockHash": "0x0dd778c8e03caa54ab1132ef560433c032ee8b08da925c2f1c74817d78c5d1d3" } ], - "blockNumber": 19809863, - "cumulativeGasUsed": "5173526", + "blockNumber": 20388710, + "cumulativeGasUsed": "4765082", "status": 1, "byzantium": true }, @@ -1273,10 +1263,10 @@ "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1" ], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_homeSpread\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"_totalScore\",\"type\":\"int256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/NBAMarketFactoryV3.sol\":\"NBAMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, InvalidName)\\n HasSpreadMarket(Spread, InvalidName)\\n HasOverUnderMarket(OverUnder, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x0d4c083d82b07c94a03831f3b79e9cdc1f6016c3532199b03cbd7d81b7d2a757\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405260006007553480156200001657600080fd5b5060405162005c6c38038062005c6c83398101604081905262000039916200058b565b60408051808201825260058152640312e322e360dc1b60208083019190915282518084018452600a80825269139bc810dbdb9d195cdd60b21b82840181905285518087018752828152808501829052865180880190975291865292850192909252600080546001600160a01b03808e166001600160a01b03199283163317831617835560018054828f1690841617815560098d905560028054928d16929093169190911782559495879591949192908e8e8e8e8e8e8188602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b3906200015990869060001990600401620006a7565b602060405180830381600087803b1580156200017457600080fd5b505af115801562000189573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001af91906200067e565b50600a620001bc62000354565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b03909316929092178255828401518051939492936200021393928501929190910190620003ca565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200029591600984019160209091019062000434565b506101409190910151600a909101805460ff1916911515919091179055505050600e85905550508151620002d29150600f90602084019062000472565b50505060108290558051620002ef90601190602084019062000472565b505050601282905580516200030c90601390602084019062000472565b5050601480546001600160a01b0319166001600160a01b0393909316929092179091555080516200034590601590602084019062000472565b505050505050505050620006d9565b6200035e620004f4565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b82805482825590600052602060002090810192821562000422579160200282015b828111156200042257825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620003eb565b506200043092915062000562565b5090565b82805482825590600052602060002090810192821562000422579160200282015b828111156200042257825182559160200191906001019062000455565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620004aa576000855562000422565b82601f10620004c557805160ff191683800117855562000422565b828001600101855582156200042257918201828111156200042257825182559160200191906001019062000455565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b8082111562000430576000815560010162000563565b80516200058681620006c0565b919050565b6000806000806000806000610120888a031215620005a7578283fd5b8751620005b481620006c0565b80975050602080890151620005c981620006c0565b60408a015160608b01519198509650620005e381620006c0565b9450609f89018a13620005f4578384fd5b604051606081016001600160401b03811182821017156200061157fe5b6040528060808b0160e08c018d8111156200062a578788fd5b875b60038110156200064b578251845292850192918501916001016200062c565b508397506200065a8162000579565b9650505050505062000670610100890162000579565b905092959891949750929550565b60006020828403121562000690578081fd5b81518015158114620006a0578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0381168114620006d657600080fd5b50565b61558380620006e96000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212202741d3829116ec5a3b52db06d6084b7bcf6547e81181634133ca8c34ab17f86264736f6c63430007060033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212202741d3829116ec5a3b52db06d6084b7bcf6547e81181634133ca8c34ab17f86264736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_homeSpread\",\"type\":\"int256\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/NBAMarketFactoryV3.sol\":\"NBAMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/NBAMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant Spread = 0;\\n string constant InvalidName = \\\"No Contest\\\";\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"1.5.0\\\")\\n ManagedByLink(_linkNode)\\n HasSpreadMarket(Spread, InvalidName)\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n makeLine(_homeSpread),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\\n internal\\n returns (uint256[] memory _marketIds)\\n {\\n _marketIds = new uint256[](1);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n }\\n\\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\\n _line = build1Line();\\n _line[0] = addHalfPoint(_homeSpread);\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x2187210295b55bd841518dc83cb592ef7365c4d7ba4f38895865e4d26ccefe35\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006007553480156200001657600080fd5b506040516200564338038062005643833981016040819052620000399162000526565b60408051808201825260058152640312e352e360dc1b6020808301919091528251808401909352600a835269139bc810dbdb9d195cdd60b21b90830152600080546001600160a01b03808c166001600160a01b03199283163317831617835560018054828d1690841617905560098a905560028054918a169190921617905590918391908a8a8a8a8a8a8188602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b3906200012e9086906000199060040162000642565b602060405180830381600087803b1580156200014957600080fd5b505af11580156200015e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000184919062000619565b50600a62000191620002ef565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b0390931692909217825582840151805193949293620001e89392850192919091019062000365565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200026a916009840191602090910190620003cf565b506101409190910151600a909101805460ff1916911515919091179055505050600e85905550508151620002a79150600f9060208401906200040d565b5050601080546001600160a01b0319166001600160a01b039390931692909217909155508051620002e09060119060208401906200040d565b50505050505050505062000674565b620002f96200048f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b828054828255906000526020600020908101928215620003bd579160200282015b82811115620003bd57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000386565b50620003cb929150620004fd565b5090565b828054828255906000526020600020908101928215620003bd579160200282015b82811115620003bd578251825591602001919060010190620003f0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620004455760008555620003bd565b82601f106200046057805160ff1916838001178555620003bd565b82800160010185558215620003bd5791820182811115620003bd578251825591602001919060010190620003f0565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b80821115620003cb5760008155600101620004fe565b805162000521816200065b565b919050565b6000806000806000806000610120888a03121562000542578283fd5b87516200054f816200065b565b8097505060208089015162000564816200065b565b60408a015160608b015191985096506200057e816200065b565b9450609f89018a136200058f578384fd5b604051606081016001600160401b0381118282101715620005ac57fe5b6040528060808b0160e08c018d811115620005c5578788fd5b875b6003811015620005e657825184529285019291850191600101620005c7565b50839750620005f58162000514565b965050505050506200060b610100890162000514565b905092959891949750929550565b6000602082840312156200062b578081fd5b815180151581146200063b578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03811681146200067157600080fd5b50565b614fbf80620006846000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063dfa558b11462000513578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039b1565b60405180910390f35b620002be620002b83660046200371f565b6200068e565b005b620002be620002d136600462003441565b620009bb565b620002ee620002e83660046200371f565b62000a09565b6040516200029e919062003b63565b620002ee6200030e366004620035d5565b62000e44565b620002ee62000325366004620035d5565b62000e6b565b620002ee6200033c36600462003424565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e91906200392c565b620002ee6200105a565b6200037962001060565b6040516200029e9190620038db565b6200039f62000399366004620035d5565b6200106f565b6040516200029e919062003941565b620003c5620003bf366004620035d5565b620011f9565b6040516200029e919062003b2a565b620002ee6200146b565b620002ee62001471565b620002be620003f9366004620035d5565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e36600462003424565b620014b8565b620002be62000445366004620035d5565b62001574565b620002ee6200045c36600462003607565b62001591565b620002ee62000473366004620035d5565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e366004620035d5565b620019d1565b6040516200029e9897969594939291906200394c565b620002ee620004cb366004620035d5565b62001b37565b62000356620004e2366004620035d5565b62001b3e565b6200037962001be8565b620002be62000503366004620035d5565b62001bf7565b6200037962001c14565b620003566200052436600462003689565b62001c23565b620002be6200053b36600462003424565b62001c73565b620002ee620005523660046200347c565b62001cdf565b6200056f62000569366004620035d5565b62001d2d565b6040516200029e919062003a59565b620002ee62001ecc565b620002be6200059936600462003635565b62001ed2565b6200039f620005b036600462003424565b62002446565b620005cd620005c7366004620035d5565b620024b0565b6040516200029e92919062003b3f565b620002ee620005ee366004620035d5565b620024e9565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd906200071090339030908690600401620038ef565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200076691906200353a565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003913565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cea565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003913565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250b90919063ffffffff16565b9062002536565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250b90919063ffffffff16565b905062000cdc8162000cd585856200254c565b906200254c565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003913565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f91906200353a565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b63565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df891906200353a565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cea565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003913565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c91906200353a565b505b905090565b6060600062000f9162002562565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b1565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620031a4565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003913565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c91906200353a565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062003a2e565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001773903390600401620038db565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c99190620035ee565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250b90919063ffffffff16565b90506200182382826200254c565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003913565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c891906200353a565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003559565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e979695949392919062003ba5565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6010546060906001600160a01b0316331462001c3e57600080fd5b62001c4a87866200261d565b905062001c68888262001c5d856200266b565b868a898d8c620026a3565b979650505050505050565b6000546001600160a01b0316331462001c8b57600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d255762001d1a62001d1286838151811062001d0357fe5b60200260200101518662001591565b839062002865565b915060010162001ce4565b509392505050565b62001d37620031f8565b600a54821062001d535762001d4b62002878565b905062000e66565b600a828154811062001d6157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc6575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001eaa57602002820191906000526020600020905b81548152602001906001019080831162001e95575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6010546001600160a01b0316331462001eea57600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0b57fe5b1462001f1657600080fd5b600286600481111562001f2557fe5b60ff16101562001f3457600080fd5b60408051610140810190915281546200219a91908390829060ff16600481111562001f5b57fe5b600481111562001f6757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fbc57602002820191906000526020600020905b81548152602001906001019080831162001fa7575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201657602002820191906000526020600020905b81548152602001906001019080831162002001575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020da5780601f10620020ae57610100808354040283529160200191620020da565b820191906000526020600020905b815481529060010190602001808311620020bc57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021725780601f10620021465761010080835404028352916020019162002172565b820191906000526020600020905b8154815290600101906020018083116200215457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028ee565b15620021b157620021ab8762002946565b62002414565b60408051610140810190915281546200241491908390829060ff166004811115620021d857fe5b6004811115620021e457fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223957602002820191906000526020600020905b81548152602001906001019080831162002224575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229357602002820191906000526020600020905b8154815260200190600101908083116200227e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023575780601f106200232b5761010080835404028352916020019162002357565b820191906000526020600020905b8154815290600101906020018083116200233957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ef5780601f10620023c357610100808354040283529160200191620023ef565b820191906000526020600020905b815481529060010190602001808311620023d157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029fc565b80548690829060ff191660018360048111156200242d57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245f57600080fd5b6001600160a01b0382166200247357600080fd5b6000546200248b906001600160a01b03168362002a3c565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024ba620031a4565b6000600c8381548110620024ca57fe5b90600052602060002001549050620024e281620011f9565b9150915091565b600c8181548110620024fa57600080fd5b600091825260209091200154905081565b6000826200251c575060006200156e565b828202828482816200252a57fe5b041462000e3d57600080fd5b6000808284816200254357fe5b04949350505050565b6000828211156200255c57600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258257fe5b906000526020600020015490506200259a81620025b1565b15620025a7576001909201915b5060010162002567565b600080620025bf8362001b3e565b90506000805b825181101562001d25576000838281518110620025de57fe5b602002602001015190508060001415801562002602575062002600816200106f565b155b156200261357600192505062001d25565b50600101620025c5565b604080516001808252818301909252606091602080830190803683370190505090506200264b838362002a40565b816000815181106200265957fe5b60200260200101818152505092915050565b60606200267762002aef565b9050620026848262002b14565b816000815181106200269257fe5b602002602001018181525050919050565b6000888152600b602052604081205460ff166004811115620026c157fe5b14620026e15760405162461bcd60e51b8152600401620015bd9062003a08565b60005b8751811015620027245788600d60008a84815181106200270057fe5b602090810291909101810151825281019190915260400160002055600101620026e4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027869391909101918a019062003266565b506000888152600b602090815260409091208751620027ae9260029092019189019062003266565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027eb92600690920191850190620032b6565b506000888152600b6020908152604090912082516200281392600790920191840190620032b6565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200285398979695949392919062003c6a565b60405180910390a15050505050505050565b60008282018381101562000e3d57600080fd5b62002882620031f8565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6000600382148160028760048111156200290457fe5b60808a015160a08b015192909114159250871415908614158380620029265750825b806200292f5750815b80620029385750805b9a9950505050505050505050565b6000818152600b6020908152604080832060010180548251818502810185019093528083529192909190830182828015620029a157602002820191906000526020600020905b8154815260200190600101908083116200298c575b5050505050905060005b8151811015620029f7576000828281518110620029c457fe5b602002602001015190508060001415620029df5750620029ee565b620029ec81600062002b70565b505b600101620029ab565b505050565b620029f7836020015160008151811062002a1257fe5b6020026020010151846040015160008151811062002a2c57fe5b6020026020010151848462002c99565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002ad45780601f1062002aa85761010080835404028352916020019162002ad4565b820191906000526020600020905b81548152906001019060200180831162002ab657829003601f168201915b5050505050848462002ae96001600262002cbd565b62002dd1565b6040805160018082528183019092526060916020808301908036833701905050905090565b600080821215801562002b285750600a8207155b1562002b3957506005810162000e66565b60008212801562002b565750600a826000038162002b5357fe5b07155b1562002b685750600419810162000e66565b508062000e66565b6000600a838154811062002b8057fe5b90600052602060002090600b02019050600081600101838154811062002ba257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002c2157600080fd5b505afa15801562002c36573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c60919081019062003559565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b6c565b600062002ca883838662002dfe565b905062002cb6858262002b70565b5050505050565b606060008362002ccf57600062002cd2565b60015b60ff16830190508067ffffffffffffffff8111801562002cf157600080fd5b5060405190808252806020026020018201604052801562002d1c578160200160208202803683370190505b509150831562002d4a57670de0b6b3a76400008260008151811062002d3d57fe5b6020026020010181815250505b6000838562002d63576802b5e3af16b188000062002d6e565b6802a802f8630a2400005b68ffffffffffffffffff168162002d8157fe5b04905060008562002d9457600062002d97565b60015b60ff1690505b8281101562002dc8578184828151811062002db457fe5b602090810291909101015260010162002d9d565b50505092915050565b60008062002de186868662002e36565b905062002df2338285600162002ebb565b9150505b949350505050565b60008382018381131562002e1757600291505062000e3d565b8381121562002e2b57600191505062000e3d565b600091505062000e3d565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e4e579050509050838160008151811062002e7557fe5b6020026020010181905250818160018151811062002e8f57fe5b6020026020010181905250828160028151811062002ea957fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002eea8730620030af565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f8a9392850192919091019062003338565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200300c91600984019160209091019062003266565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200305f9083908790879062003bf3565b60405180910390a1811562002df6577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200309f919062003b63565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff81118015620030ce57600080fd5b50604051908082528060200260200182016040528015620030f9578160200160208202803683370190505b50905060005b828110156200319b578581815181106200311557fe5b60200260200101518682815181106200312a57fe5b602002602001015186604051620031419062003390565b6200314f93929190620039c6565b604051809103906000f0801580156200316c573d6000803e3d6000fd5b508282815181106200317a57fe5b6001600160a01b0390921660209283029190910190910152600101620030ff565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620032a4579160200282015b82811115620032a457825182559160200191906001019062003287565b50620032b29291506200339e565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ee5760008555620032a4565b82601f106200330957805160ff1916838001178555620032a4565b82800160010185558215620032a45791820182811115620032a457825182559160200191906001019062003287565b828054828255906000526020600020908101928215620032a4579160200282015b82811115620032a457825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003359565b6111f38062003d9783390190565b5b80821115620032b257600081556001016200339f565b80356001600160a01b038116811462000e6657600080fd5b600082601f830112620033de578081fd5b8135620033f5620033ef8262003d2e565b62003d09565b8181528460208386010111156200340a578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003436578081fd5b62000e3d82620033b5565b6000806040838503121562003454578081fd5b6200345f83620033b5565b91506020830135620034718162003d84565b809150509250929050565b600080604083850312156200348f578182fd5b823567ffffffffffffffff80821115620034a7578384fd5b818501915085601f830112620034bb578384fd5b8135602082821115620034ca57fe5b8082029250620034dc81840162003d09565b8281528181019085830185870184018b1015620034f7578889fd5b8896505b848710156200351b578035835260019690960195918301918301620034fb565b5096506200352d9050878201620033b5565b9450505050509250929050565b6000602082840312156200354c578081fd5b815162000e3d8162003d84565b6000602082840312156200356b578081fd5b815167ffffffffffffffff81111562003582578182fd5b8201601f8101841362003593578182fd5b8051620035a4620033ef8262003d2e565b818152856020838501011115620035b9578384fd5b620035cc82602083016020860162003d51565b95945050505050565b600060208284031215620035e7578081fd5b5035919050565b60006020828403121562003600578081fd5b5051919050565b600080604083850312156200361a578182fd5b823591506200362c60208401620033b5565b90509250929050565b60008060008060008060c087890312156200364e578182fd5b8635955060208701356005811062003664578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600060e0888a031215620036a4578081fd5b87359650602088013567ffffffffffffffff80821115620036c3578283fd5b620036d18b838c01620033cd565b975060408a0135965060608a0135915080821115620036ee578283fd5b50620036fd8a828b01620033cd565b979a969950949760808101359660a0820135965060c090910135945092505050565b60008060006060848603121562003734578081fd5b83359250602084013591506200374d60408501620033b5565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156200379d5781516001600160a01b03168752958201959082019060010162003776565b509495945050505050565b6000815180845260208085019450808401835b838110156200379d57815187529582019590820190600101620037bb565b15159052565b60058110620037ea57fe5b9052565b600081518084526200380881602086016020860162003d51565b601f01601f19169290920160200192915050565b60006101406200382e848451620037df565b60208301518160208601526200384782860182620037a8565b91505060408301518482036040860152620038638282620037a8565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c08601526200389d8282620037ee565b91505060e083015184820360e0860152620038b98282620037ee565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d6020830184620037a8565b901515815260200190565b60006101006200395d838c620037df565b8960208401528860408401528760608401528060808401526200398381840188620037ee565b905082810360a0840152620039998187620037ee565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d6020830184620037ee565b600060608252620039db6060830186620037ee565b8281036020840152620039ef8186620037ee565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a6f60208301845162003756565b602083015161016080604085015262003a8d61018085018362003763565b9150604085015162003aa3606086018262003756565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b098483620037a8565b93508087015191505062003b2082860182620037d9565b5090949350505050565b60006020825262000e3d60208301846200381c565b60006040825262003b5460408301856200381c565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003b9b6080830184620037ee565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e0606083015262003bd460e0830187620037ee565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5157607f1988870301845262003c3e868351620037ee565b9550928401929084019060010162003c1f565b5050505050828103604084015262002df28185620037a8565b60006101008a835280602084015262003c868184018b620037a8565b9050828103604084015262003c9c818a620037a8565b905087606084015286608084015282810360a084015262003cbe8187620037ee565b905082810360c084015262003cd48186620037ee565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2657fe5b604052919050565b600067ffffffffffffffff82111562003d4357fe5b50601f01601f191660200190565b60005b8381101562003d6e57818101518382015260200162003d54565b8381111562003d7e576000848401525b50505050565b801515811462003d9357600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220473d8bf6197b71a387958afce88bf57753398a9e6ff7edb50dca3b5ac2b2da9b64736f6c63430007060033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ec9790821162000087578063ec979082146200057e578063ee750b191462000588578063f2fde38b146200059f578063f563c99a14620005b6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063dfa558b11462000513578063e2c30b15146200052a578063e5678dfa1462000541578063eb44fdd314620005585762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e9190620039b1565b60405180910390f35b620002be620002b83660046200371f565b6200068e565b005b620002be620002d136600462003441565b620009bb565b620002ee620002e83660046200371f565b62000a09565b6040516200029e919062003b63565b620002ee6200030e366004620035d5565b62000e44565b620002ee62000325366004620035d5565b62000e6b565b620002ee6200033c36600462003424565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e91906200392c565b620002ee6200105a565b6200037962001060565b6040516200029e9190620038db565b6200039f62000399366004620035d5565b6200106f565b6040516200029e919062003941565b620003c5620003bf366004620035d5565b620011f9565b6040516200029e919062003b2a565b620002ee6200146b565b620002ee62001471565b620002be620003f9366004620035d5565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e36600462003424565b620014b8565b620002be62000445366004620035d5565b62001574565b620002ee6200045c36600462003607565b62001591565b620002ee62000473366004620035d5565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e366004620035d5565b620019d1565b6040516200029e9897969594939291906200394c565b620002ee620004cb366004620035d5565b62001b37565b62000356620004e2366004620035d5565b62001b3e565b6200037962001be8565b620002be62000503366004620035d5565b62001bf7565b6200037962001c14565b620003566200052436600462003689565b62001c23565b620002be6200053b36600462003424565b62001c73565b620002ee620005523660046200347c565b62001cdf565b6200056f62000569366004620035d5565b62001d2d565b6040516200029e919062003a59565b620002ee62001ecc565b620002be6200059936600462003635565b62001ed2565b6200039f620005b036600462003424565b62002446565b620005cd620005c7366004620035d5565b620024b0565b6040516200029e92919062003b3f565b620002ee620005ee366004620035d5565b620024e9565b60118054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd906200071090339030908690600401620038ef565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200076691906200353a565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003913565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac9392919062003cea565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003913565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250b90919063ffffffff16565b9062002536565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250b90919063ffffffff16565b905062000cdc8162000cd585856200254c565b906200254c565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003913565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f91906200353a565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162003b63565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df891906200353a565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e9392919062003cea565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003913565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c91906200353a565b505b905090565b6060600062000f9162002562565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b1565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620031a4565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003913565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c91906200353a565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062003a2e565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b039091169063712977849062001773903390600401620038db565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c99190620035ee565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250b90919063ffffffff16565b90506200182382826200254c565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003913565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c891906200353a565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003559565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e979695949392919062003ba5565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6010546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6010546060906001600160a01b0316331462001c3e57600080fd5b62001c4a87866200261d565b905062001c68888262001c5d856200266b565b868a898d8c620026a3565b979650505050505050565b6000546001600160a01b0316331462001c8b57600080fd5b601080546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001d255762001d1a62001d1286838151811062001d0357fe5b60200260200101518662001591565b839062002865565b915060010162001ce4565b509392505050565b62001d37620031f8565b600a54821062001d535762001d4b62002878565b905062000e66565b600a828154811062001d6157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001de557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001dc6575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001eaa57602002820191906000526020600020905b81548152602001906001019080831162001e95575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6010546001600160a01b0316331462001eea57600080fd5b6000868152600b602052604090206001815460ff16600481111562001f0b57fe5b1462001f1657600080fd5b600286600481111562001f2557fe5b60ff16101562001f3457600080fd5b60408051610140810190915281546200219a91908390829060ff16600481111562001f5b57fe5b600481111562001f6757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001fbc57602002820191906000526020600020905b81548152602001906001019080831162001fa7575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200201657602002820191906000526020600020905b81548152602001906001019080831162002001575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620020da5780601f10620020ae57610100808354040283529160200191620020da565b820191906000526020600020905b815481529060010190602001808311620020bc57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021725780601f10620021465761010080835404028352916020019162002172565b820191906000526020600020905b8154815290600101906020018083116200215457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620028ee565b15620021b157620021ab8762002946565b62002414565b60408051610140810190915281546200241491908390829060ff166004811115620021d857fe5b6004811115620021e457fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200223957602002820191906000526020600020905b81548152602001906001019080831162002224575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200229357602002820191906000526020600020905b8154815260200190600101908083116200227e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023575780601f106200232b5761010080835404028352916020019162002357565b820191906000526020600020905b8154815290600101906020018083116200233957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620023ef5780601f10620023c357610100808354040283529160200191620023ef565b820191906000526020600020905b815481529060010190602001808311620023d157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620029fc565b80548690829060ff191660018360048111156200242d57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200245f57600080fd5b6001600160a01b0382166200247357600080fd5b6000546200248b906001600160a01b03168362002a3c565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b620024ba620031a4565b6000600c8381548110620024ca57fe5b90600052602060002001549050620024e281620011f9565b9150915091565b600c8181548110620024fa57600080fd5b600091825260209091200154905081565b6000826200251c575060006200156e565b828202828482816200252a57fe5b041462000e3d57600080fd5b6000808284816200254357fe5b04949350505050565b6000828211156200255c57600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258257fe5b906000526020600020015490506200259a81620025b1565b15620025a7576001909201915b5060010162002567565b600080620025bf8362001b3e565b90506000805b825181101562001d25576000838281518110620025de57fe5b602002602001015190508060001415801562002602575062002600816200106f565b155b156200261357600192505062001d25565b50600101620025c5565b604080516001808252818301909252606091602080830190803683370190505090506200264b838362002a40565b816000815181106200265957fe5b60200260200101818152505092915050565b60606200267762002aef565b9050620026848262002b14565b816000815181106200269257fe5b602002602001018181525050919050565b6000888152600b602052604081205460ff166004811115620026c157fe5b14620026e15760405162461bcd60e51b8152600401620015bd9062003a08565b60005b8751811015620027245788600d60008a84815181106200270057fe5b602090810291909101810151825281019190915260400160002055600101620026e4565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff1916831781558951620027869391909101918a019062003266565b506000888152600b602090815260409091208751620027ae9260029092019189019062003266565b506000888152600b602090815260409091206003810187905560048101869055600581018590558351620027eb92600690920191850190620032b6565b506000888152600b6020908152604090912082516200281392600790920191840190620032b6565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c6040516200285398979695949392919062003c6a565b60405180910390a15050505050505050565b60008282018381101562000e3d57600080fd5b62002882620031f8565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b6000600382148160028760048111156200290457fe5b60808a015160a08b015192909114159250871415908614158380620029265750825b806200292f5750815b80620029385750805b9a9950505050505050505050565b6000818152600b6020908152604080832060010180548251818502810185019093528083529192909190830182828015620029a157602002820191906000526020600020905b8154815260200190600101908083116200298c575b5050505050905060005b8151811015620029f7576000828281518110620029c457fe5b602002602001015190508060001415620029df5750620029ee565b620029ec81600062002b70565b505b600101620029ab565b505050565b620029f7836020015160008151811062002a1257fe5b6020026020010151846040015160008151811062002a2c57fe5b6020026020010151848462002c99565b5050565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002ad45780601f1062002aa85761010080835404028352916020019162002ad4565b820191906000526020600020905b81548152906001019060200180831162002ab657829003601f168201915b5050505050848462002ae96001600262002cbd565b62002dd1565b6040805160018082528183019092526060916020808301908036833701905050905090565b600080821215801562002b285750600a8207155b1562002b3957506005810162000e66565b60008212801562002b565750600a826000038162002b5357fe5b07155b1562002b685750600419810162000e66565b508062000e66565b6000600a838154811062002b8057fe5b90600052602060002090600b02019050600081600101838154811062002ba257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002c2157600080fd5b505afa15801562002c36573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c60919081019062003559565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac949392919062003b6c565b600062002ca883838662002dfe565b905062002cb6858262002b70565b5050505050565b606060008362002ccf57600062002cd2565b60015b60ff16830190508067ffffffffffffffff8111801562002cf157600080fd5b5060405190808252806020026020018201604052801562002d1c578160200160208202803683370190505b509150831562002d4a57670de0b6b3a76400008260008151811062002d3d57fe5b6020026020010181815250505b6000838562002d63576802b5e3af16b188000062002d6e565b6802a802f8630a2400005b68ffffffffffffffffff168162002d8157fe5b04905060008562002d9457600062002d97565b60015b60ff1690505b8281101562002dc8578184828151811062002db457fe5b602090810291909101015260010162002d9d565b50505092915050565b60008062002de186868662002e36565b905062002df2338285600162002ebb565b9150505b949350505050565b60008382018381131562002e1757600291505062000e3d565b8381121562002e2b57600191505062000e3d565b600091505062000e3d565b60408051600380825260808201909252606091816020015b606081526020019060019003908162002e4e579050509050838160008151811062002e7557fe5b6020026020010181905250818160018151811062002e8f57fe5b6020026020010181905250828160028151811062002ea957fe5b60200260200101819052509392505050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162002eea8730620030af565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b039092169190911781558282015180519394919362002f8a9392850192919091019062003338565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e08201516007820155610100820151600882015561012082015180516200300c91600984019160209091019062003266565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200305f9083908790879062003bf3565b60405180910390a1811562002df6577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f88816040516200309f919062003b63565b60405180910390a1949350505050565b815160609060008167ffffffffffffffff81118015620030ce57600080fd5b50604051908082528060200260200182016040528015620030f9578160200160208202803683370190505b50905060005b828110156200319b578581815181106200311557fe5b60200260200101518682815181106200312a57fe5b602002602001015186604051620031419062003390565b6200314f93929190620039c6565b604051809103906000f0801580156200316c573d6000803e3d6000fd5b508282815181106200317a57fe5b6001600160a01b0390921660209283029190910190910152600101620030ff565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620032a4579160200282015b82811115620032a457825182559160200191906001019062003287565b50620032b29291506200339e565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620032ee5760008555620032a4565b82601f106200330957805160ff1916838001178555620032a4565b82800160010185558215620032a45791820182811115620032a457825182559160200191906001019062003287565b828054828255906000526020600020908101928215620032a4579160200282015b82811115620032a457825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062003359565b6111f38062003d9783390190565b5b80821115620032b257600081556001016200339f565b80356001600160a01b038116811462000e6657600080fd5b600082601f830112620033de578081fd5b8135620033f5620033ef8262003d2e565b62003d09565b8181528460208386010111156200340a578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121562003436578081fd5b62000e3d82620033b5565b6000806040838503121562003454578081fd5b6200345f83620033b5565b91506020830135620034718162003d84565b809150509250929050565b600080604083850312156200348f578182fd5b823567ffffffffffffffff80821115620034a7578384fd5b818501915085601f830112620034bb578384fd5b8135602082821115620034ca57fe5b8082029250620034dc81840162003d09565b8281528181019085830185870184018b1015620034f7578889fd5b8896505b848710156200351b578035835260019690960195918301918301620034fb565b5096506200352d9050878201620033b5565b9450505050509250929050565b6000602082840312156200354c578081fd5b815162000e3d8162003d84565b6000602082840312156200356b578081fd5b815167ffffffffffffffff81111562003582578182fd5b8201601f8101841362003593578182fd5b8051620035a4620033ef8262003d2e565b818152856020838501011115620035b9578384fd5b620035cc82602083016020860162003d51565b95945050505050565b600060208284031215620035e7578081fd5b5035919050565b60006020828403121562003600578081fd5b5051919050565b600080604083850312156200361a578182fd5b823591506200362c60208401620033b5565b90509250929050565b60008060008060008060c087890312156200364e578182fd5b8635955060208701356005811062003664578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b600080600080600080600060e0888a031215620036a4578081fd5b87359650602088013567ffffffffffffffff80821115620036c3578283fd5b620036d18b838c01620033cd565b975060408a0135965060608a0135915080821115620036ee578283fd5b50620036fd8a828b01620033cd565b979a969950949760808101359660a0820135965060c090910135945092505050565b60008060006060848603121562003734578081fd5b83359250602084013591506200374d60408501620033b5565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b838110156200379d5781516001600160a01b03168752958201959082019060010162003776565b509495945050505050565b6000815180845260208085019450808401835b838110156200379d57815187529582019590820190600101620037bb565b15159052565b60058110620037ea57fe5b9052565b600081518084526200380881602086016020860162003d51565b601f01601f19169290920160200192915050565b60006101406200382e848451620037df565b60208301518160208601526200384782860182620037a8565b91505060408301518482036040860152620038638282620037a8565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c08601526200389d8282620037ee565b91505060e083015184820360e0860152620038b98282620037ee565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d6020830184620037a8565b901515815260200190565b60006101006200395d838c620037df565b8960208401528860408401528760608401528060808401526200398381840188620037ee565b905082810360a0840152620039998187620037ee565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d6020830184620037ee565b600060608252620039db6060830186620037ee565b8281036020840152620039ef8186620037ee565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b60006020825262003a6f60208301845162003756565b602083015161016080604085015262003a8d61018085018362003763565b9150604085015162003aa3606086018262003756565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f19868503018187015262003b098483620037a8565b93508087015191505062003b2082860182620037d9565b5090949350505050565b60006020825262000e3d60208301846200381c565b60006040825262003b5460408301856200381c565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003b9b6080830184620037ee565b9695505050505050565b600088825260018060a01b038816602083015286604083015260e0606083015262003bd460e0830187620037ee565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b8281101562003c5157607f1988870301845262003c3e868351620037ee565b9550928401929084019060010162003c1f565b5050505050828103604084015262002df28185620037a8565b60006101008a835280602084015262003c868184018b620037a8565b9050828103604084015262003c9c818a620037a8565b905087606084015286608084015282810360a084015262003cbe8187620037ee565b905082810360c084015262003cd48186620037ee565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff8111828210171562003d2657fe5b604052919050565b600067ffffffffffffffff82111562003d4357fe5b50601f01601f191660200190565b60005b8381101562003d6e57818101518382015260200162003d54565b8381111562003d7e576000848401525b50505050565b801515811462003d9357600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a2646970667358221220473d8bf6197b71a387958afce88bf57753398a9e6ff7edb50dca3b5ac2b2da9b64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { @@ -1408,28 +1398,12 @@ "slot": "13", "type": "t_mapping(t_uint256,t_uint256)" }, - { - "astId": 6974, - "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", - "label": "headToHeadMarketType", - "offset": 0, - "slot": "14", - "type": "t_uint256" - }, - { - "astId": 6976, - "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", - "label": "noContestName", - "offset": 0, - "slot": "15", - "type": "t_string_storage" - }, { "astId": 7272, "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", "label": "spreadMarketType", "offset": 0, - "slot": "16", + "slot": "14", "type": "t_uint256" }, { @@ -1437,23 +1411,7 @@ "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", "label": "noContestName", "offset": 0, - "slot": "17", - "type": "t_string_storage" - }, - { - "astId": 7096, - "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", - "label": "overUnderMarketType", - "offset": 0, - "slot": "18", - "type": "t_uint256" - }, - { - "astId": 7098, - "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", - "label": "noContestName", - "offset": 0, - "slot": "19", + "slot": "15", "type": "t_string_storage" }, { @@ -1461,7 +1419,7 @@ "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", "label": "linkNode", "offset": 0, - "slot": "20", + "slot": "16", "type": "t_address" }, { @@ -1469,7 +1427,7 @@ "contract": "contracts/turbo/NBAMarketFactoryV3.sol:NBAMarketFactoryV3", "label": "version", "offset": 0, - "slot": "21", + "slot": "17", "type": "t_string_storage" } ], @@ -1479,8 +1437,8 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(OwnedERC20)25830)dyn_storage": { - "base": "t_contract(OwnedERC20)25830", + "t_array(t_contract(OwnedERC20)25781)dyn_storage": { + "base": "t_contract(OwnedERC20)25781", "encoding": "dynamic_array", "label": "contract OwnedERC20[]", "numberOfBytes": "32" @@ -1518,7 +1476,7 @@ "label": "contract IERC20Full", "numberOfBytes": "20" }, - "t_contract(OwnedERC20)25830": { + "t_contract(OwnedERC20)25781": { "encoding": "inplace", "label": "contract OwnedERC20", "numberOfBytes": "20" @@ -1577,7 +1535,7 @@ "label": "shareTokens", "offset": 0, "slot": "1", - "type": "t_array(t_contract(OwnedERC20)25830)dyn_storage" + "type": "t_array(t_contract(OwnedERC20)25781)dyn_storage" }, { "astId": 15185, @@ -1585,7 +1543,7 @@ "label": "winner", "offset": 0, "slot": "2", - "type": "t_contract(OwnedERC20)25830" + "type": "t_contract(OwnedERC20)25781" }, { "astId": 15187, diff --git a/packages/smart/deployments/maticMumbai/NFLMarketFactoryV3.json b/packages/smart/deployments/maticMumbai/NFLMarketFactoryV3.json index d5713f9a8..2b675e1cc 100644 --- a/packages/smart/deployments/maticMumbai/NFLMarketFactoryV3.json +++ b/packages/smart/deployments/maticMumbai/NFLMarketFactoryV3.json @@ -1,5 +1,5 @@ { - "address": "0x51266210260d7d68Defdbf0D7D52378B66807570", + "address": "0xaf2ed373E031bA5c9Ad10E4686e1F5C1074639D2", "abi": [ { "inputs": [ @@ -1214,35 +1214,35 @@ "type": "function" } ], - "transactionHash": "0x1e7e2af3997ac3a6b7aa54eedf22471cf04f9bdb7c3449524393421c97885229", + "transactionHash": "0xbb5fd581480a21560fbbba16bef6658f0bd2a93bf6d5aead754be4b1d0c74c9f", "receipt": { "to": null, "from": "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", - "contractAddress": "0x51266210260d7d68Defdbf0D7D52378B66807570", - "transactionIndex": 0, - "gasUsed": "5173841", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000000000000080100000040200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000000000000000001000010000000000000000000000000100000000000000110000000000040000000000000000000000000000000000000000000100000", - "blockHash": "0x8db3b1979f69df9a156211d8d307e9e9a66c849967132f4589c54df94a476c78", - "transactionHash": "0x1e7e2af3997ac3a6b7aa54eedf22471cf04f9bdb7c3449524393421c97885229", + "contractAddress": "0xaf2ed373E031bA5c9Ad10E4686e1F5C1074639D2", + "transactionIndex": 1, + "gasUsed": "5173853", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018020000000000000010001201000000000000000008000000000000000800000000000000000080100000000200000000000000000000000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000080024000000008000000000001000000000000000000000000000000100000000000000018000000000140000000000000000000000000000000000000000000100000", + "blockHash": "0x3352f7488019d3379f33bbb17b3d8515adcaf579b7fc9546b9cf0178c477ce42", + "transactionHash": "0xbb5fd581480a21560fbbba16bef6658f0bd2a93bf6d5aead754be4b1d0c74c9f", "logs": [ { - "transactionIndex": 0, - "blockNumber": 19809874, - "transactionHash": "0x1e7e2af3997ac3a6b7aa54eedf22471cf04f9bdb7c3449524393421c97885229", + "transactionIndex": 1, + "blockNumber": 20388722, + "transactionHash": "0xbb5fd581480a21560fbbba16bef6658f0bd2a93bf6d5aead754be4b1d0c74c9f", "address": "0x5799bFe361BEea69f808328FF4884DF92f1f66f0", "topics": [ "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x00000000000000000000000051266210260d7d68defdbf0d7d52378b66807570", + "0x000000000000000000000000af2ed373e031ba5c9ad10e4686e1f5c1074639d2", "0x00000000000000000000000059ddfe9961e050bda1ed9bf9ccd009948036dd76" ], "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "logIndex": 0, - "blockHash": "0x8db3b1979f69df9a156211d8d307e9e9a66c849967132f4589c54df94a476c78" + "logIndex": 2, + "blockHash": "0x3352f7488019d3379f33bbb17b3d8515adcaf579b7fc9546b9cf0178c477ce42" }, { - "transactionIndex": 0, - "blockNumber": 19809874, - "transactionHash": "0x1e7e2af3997ac3a6b7aa54eedf22471cf04f9bdb7c3449524393421c97885229", + "transactionIndex": 1, + "blockNumber": 20388722, + "transactionHash": "0xbb5fd581480a21560fbbba16bef6658f0bd2a93bf6d5aead754be4b1d0c74c9f", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", @@ -1250,13 +1250,13 @@ "0x0000000000000000000000008c9c733ecd48426b9c53c38ccb60f3b307329be1", "0x000000000000000000000000e4b8e9222704401ad16d4d826732953daf07c7e2" ], - "data": "0x000000000000000000000000000000000000000000000000003724be30c9be00000000000000000000000000000000000000000000000003643b766be563202900000000000000000000000000000000000000000000000002a324d6bd773400000000000000000000000000000000000000000000000003640451adb499622900000000000000000000000000000000000000000000000002da4994ee40f200", - "logIndex": 1, - "blockHash": "0x8db3b1979f69df9a156211d8d307e9e9a66c849967132f4589c54df94a476c78" + "data": "0x0000000000000000000000000000000000000000000000000049865e18bd880000000000000000000000000000000000000000000000000334dac9b731702874000000000000000000000000000000000000000000000000039e72539bc3d4f00000000000000000000000000000000000000000000000033491435918b2a07400000000000000000000000000000000000000000000000003e7f8b1b4815cf0", + "logIndex": 3, + "blockHash": "0x3352f7488019d3379f33bbb17b3d8515adcaf579b7fc9546b9cf0178c477ce42" } ], - "blockNumber": 19809874, - "cumulativeGasUsed": "5173841", + "blockNumber": 20388722, + "cumulativeGasUsed": "5323913", "status": 1, "byzantium": true }, @@ -1273,10 +1273,10 @@ "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1", "0x8C9c733eCd48426b9c53c38ccB60F3b307329bE1" ], - "solcInputHash": "efe24c9fabc1d3f5df30484a07e36b33", - "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_homeSpread\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"_totalScore\",\"type\":\"int256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/NFLMarketFactoryV3.sol\":\"NFLMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) private pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x50b538dbc412132fb810bdfb0c4a27ed7d5036ad5280bff4189c0e42efe8f0f5\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/NFLMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\n// NFL is standard except ties are fine: they become NoContestOrDraw.\\n// As a consequence, half points are not added to the lines.\\ncontract NFLMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, \\\"No Contest / Draw\\\")\\n HasSpreadMarket(Spread, \\\"No Contest\\\")\\n HasOverUnderMarket(OverUnder, \\\"No Contest\\\")\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x5dae4d4a6702a986262b57e2cb655e75b9c85b12945367505231e761d66d58b8\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405260006007553480156200001657600080fd5b5060405162005c8138038062005c818339810160408190526200003991620005a0565b6040805180820182526006815265076312e322e360d41b60208083019190915282518084018452600a80825269139bc810dbdb9d195cdd60b21b8284018190528551808701875291825281840152845180860190955260118552704e6f20436f6e74657374202f204472617760781b92850192909252600080546001600160a01b03808e166001600160a01b03199283163317831617835560018054828f1690841617815560098d905560028054928d16929093169190911782559495879591949192908e8e8e8e8e8e8188602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b3906200016e90869060001990600401620006bc565b602060405180830381600087803b1580156200018957600080fd5b505af11580156200019e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001c4919062000693565b50600a620001d162000369565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b03909316929092178255828401518051939492936200022893928501929190910190620003df565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015160088201556101208201518051620002aa91600984019160209091019062000449565b506101409190910151600a909101805460ff1916911515919091179055505050600e85905550508151620002e79150600f90602084019062000487565b505050601082905580516200030490601190602084019062000487565b505050601282905580516200032190601390602084019062000487565b5050601480546001600160a01b0319166001600160a01b0393909316929092179091555080516200035a90601590602084019062000487565b505050505050505050620006ee565b6200037362000509565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b82805482825590600052602060002090810192821562000437579160200282015b828111156200043757825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000400565b506200044592915062000577565b5090565b82805482825590600052602060002090810192821562000437579160200282015b82811115620004375782518255916020019190600101906200046a565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620004bf576000855562000437565b82601f10620004da57805160ff191683800117855562000437565b82800160010185558215620004375791820182811115620004375782518255916020019190600101906200046a565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b8082111562000445576000815560010162000578565b80516200059b81620006d5565b919050565b6000806000806000806000610120888a031215620005bc578283fd5b8751620005c981620006d5565b80975050602080890151620005de81620006d5565b60408a015160608b01519198509650620005f881620006d5565b9450609f89018a1362000609578384fd5b604051606081016001600160401b03811182821017156200062657fe5b6040528060808b0160e08c018d8111156200063f578788fd5b875b6003811015620006605782518452928501929185019160010162000641565b508397506200066f816200058e565b965050505050506200068561010089016200058e565b905092959891949750929550565b600060208284031215620006a5578081fd5b81518015158114620006b5578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0381168114620006eb57600080fd5b50565b61558380620006fe6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a264697066735822122089adc15246cfa6d90d76a3bd7200570dc1cb7116d05890784d952d5f1606548e64736f6c63430007060033", - "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a264697066735822122089adc15246cfa6d90d76a3bd7200570dc1cb7116d05890784d952d5f1606548e64736f6c63430007060033", + "solcInputHash": "8300c5e3118901fdc5a46905f80222b0", + "metadata": "{\"compiler\":{\"version\":\"0.7.6+commit.7338295f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"contract IERC20Full\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_shareFactor\",\"type\":\"uint256\"},{\"internalType\":\"contract FeePot\",\"name\":\"_feePot\",\"type\":\"address\"},{\"internalType\":\"uint256[3]\",\"name\":\"_fees\",\"type\":\"uint256[3]\"},{\"internalType\":\"address\",\"name\":\"_protocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNode\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newLinkNode\",\"type\":\"address\"}],\"name\":\"LinkNodeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"}],\"name\":\"MarketActivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"names\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"}],\"name\":\"MarketCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winnerName\",\"type\":\"string\"}],\"name\":\"MarketResolved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesBurned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"SharesMinted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"}],\"name\":\"SportsEventCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"winningOutcome\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"winningIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"winningName\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payout\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"WinningsClaimed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accumulatedProtocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"accumulatedSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_sharesToBurn\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"burnShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_shares\",\"type\":\"uint256\"}],\"name\":\"calcCost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_collateralIn\",\"type\":\"uint256\"}],\"name\":\"calcShares\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimManyWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"claimProtocolFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimSettlementFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimWinnings\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20Full\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_homeTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_startTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_homeSpread\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"_totalScore\",\"type\":\"int256\"},{\"internalType\":\"int256[2]\",\"name\":\"_moneylines\",\"type\":\"int256[2]\"}],\"name\":\"createEvent\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_marketIds\",\"type\":\"uint256[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eventCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feePot\",\"outputs\":[{\"internalType\":\"contract FeePot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getEventMarkets\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_markets\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"getMarket\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"settlementAddress\",\"type\":\"address\"},{\"internalType\":\"contract OwnedERC20[]\",\"name\":\"shareTokens\",\"type\":\"address[]\"},{\"internalType\":\"contract OwnedERC20\",\"name\":\"winner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"winnerIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"settlementFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"protocolFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stakerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"creationTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"resolutionTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"initialOdds\",\"type\":\"uint256[]\"},{\"internalType\":\"bool\",\"name\":\"active\",\"type\":\"bool\"}],\"internalType\":\"struct AbstractMarketFactoryV3.Market\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_marketId\",\"type\":\"uint256\"}],\"name\":\"getRewardEndTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"name\":\"getSportsEvent\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getSportsEventByIndex\",\"outputs\":[{\"components\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256[]\",\"name\":\"markets\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"lines\",\"type\":\"int256[]\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"internalType\":\"struct Sport.SportsEvent\",\"name\":\"_event\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"isMarketResolved\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkNode\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"listOfSportsEvents\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"listResolvableEvents\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"marketCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"marketIdToEventIdMapping\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_shareToMint\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"mintShares\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocol\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_eventId\",\"type\":\"uint256\"},{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"_eventStatus\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"_homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_awayScore\",\"type\":\"uint256\"}],\"name\":\"resolveEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newLinkNode\",\"type\":\"address\"}],\"name\":\"setLinkNode\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newProtocol\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_claimFirst\",\"type\":\"bool\"}],\"name\":\"setProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setProtocolFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setSettlementFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_newFee\",\"type\":\"uint256\"}],\"name\":\"setStakerFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"settlementFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"shareFactor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"sportsEvents\",\"outputs\":[{\"internalType\":\"enum Sport.SportsEventStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"estimatedStartTime\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"homeTeamId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayTeamId\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"homeTeamName\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"awayTeamName\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"homeScore\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"awayScore\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stakerFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"_newOwner\":\"The address to transfer ownership to.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/turbo/NFLMarketFactoryV3.sol\":\"NFLMarketFactoryV3\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n *\\n * _Available since v3.4._\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a, \\\"SafeMath: subtraction overflow\\\");\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a == 0) return 0;\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: division by zero\\\");\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b > 0, \\\"SafeMath: modulo by zero\\\");\\n return a % b;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {trySub}.\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n return a - b;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryDiv}.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a / b;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * reverting with custom message when dividing by zero.\\n *\\n * CAUTION: This function is deprecated because it requires allocating memory for the error\\n * message unnecessarily. For custom revert reasons use {tryMod}.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0xe22a1fc7400ae196eba2ad1562d0386462b00a6363b742d55a2fd2021a58586f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\nimport \\\"../../utils/Context.sol\\\";\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin guidelines: functions revert instead\\n * of returning `false` on failure. This behavior is nonetheless conventional\\n * and does not conflict with the expectations of ERC20 applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20 {\\n using SafeMath for uint256;\\n\\n mapping (address => uint256) private _balances;\\n\\n mapping (address => mapping (address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n uint8 private _decimals;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\\n * a default value of 18.\\n *\\n * To select a different value for {decimals}, use {_setupDecimals}.\\n *\\n * All three of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor (string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n _decimals = 18;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\\n * called.\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual returns (uint8) {\\n return _decimals;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \\\"ERC20: transfer amount exceeds allowance\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \\\"ERC20: decreased allowance below zero\\\"));\\n return true;\\n }\\n\\n /**\\n * @dev Moves tokens `amount` from `sender` to `recipient`.\\n *\\n * This is internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n _balances[sender] = _balances[sender].sub(amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n _balances[recipient] = _balances[recipient].add(amount);\\n emit Transfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply = _totalSupply.add(amount);\\n _balances[account] = _balances[account].add(amount);\\n emit Transfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n _balances[account] = _balances[account].sub(amount, \\\"ERC20: burn amount exceeds balance\\\");\\n _totalSupply = _totalSupply.sub(amount);\\n emit Transfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Sets {decimals} to a value other than the default one of 18.\\n *\\n * WARNING: This function should only be called from the constructor. Most\\n * applications that interact with token contracts will not expect\\n * {decimals} to ever change, and may work incorrectly if it does.\\n */\\n function _setupDecimals(uint8 decimals_) internal virtual {\\n _decimals = decimals_;\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be to transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\\n}\\n\",\"keccak256\":\"0x36b5ca4eabe888b39b10973621ca0dcc9b1508f8d06db9ddf045d7aa7c867d4a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.7.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0xbd74f587ab9b9711801baf667db1426e4a03fd2d7f15af33e0e0d0394e7cef76\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"contracts/balancer/BColor.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface BColor {\\n function getColor() external view returns (bytes32);\\n}\\n\\ncontract BBronze is BColor {\\n function getColor() external pure override returns (bytes32) {\\n return bytes32(\\\"BRONZE\\\");\\n }\\n}\\n\",\"keccak256\":\"0xc716fe6583bbf6f8546c258540b2f7527dbc3b1f4b30007a0978b620c9779378\",\"license\":\"MIT\"},\"contracts/balancer/BConst.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BColor.sol\\\";\\n\\ncontract BConst is BBronze {\\n uint256 public constant BONE = 10**18;\\n\\n uint256 public constant MIN_BOUND_TOKENS = 2;\\n uint256 public constant MAX_BOUND_TOKENS = 8;\\n\\n uint256 public constant MIN_FEE = BONE / 10**6;\\n uint256 public constant MAX_FEE = BONE / 10;\\n uint256 public constant EXIT_FEE = 0;\\n\\n uint256 public constant MIN_WEIGHT = BONE;\\n uint256 public constant MAX_WEIGHT = BONE * 50;\\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\\n uint256 public constant MIN_BALANCE = BONE / 10**12;\\n\\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\\n\\n uint256 public constant MIN_BPOW_BASE = 1 wei;\\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\\n\\n uint256 public constant MAX_IN_RATIO = BONE / 2;\\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\\n}\\n\",\"keccak256\":\"0xb8d5d4ae9948f9be6ddb3111b38f01a15a607a155010321c4666351c9ca9afec\",\"license\":\"MIT\"},\"contracts/balancer/BMath.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ncontract BMath is BBronze, BConst, BNum {\\n /**********************************************************************************************\\n // calcSpotPrice //\\n // sP = spotPrice //\\n // bI = tokenBalanceIn ( bI / wI ) 1 //\\n // bO = tokenBalanceOut sP = ----------- * ---------- //\\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcSpotPrice(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 swapFee\\n ) public pure returns (uint256 spotPrice) {\\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\\n uint256 ratio = bdiv(numer, denom);\\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\\n return (spotPrice = bmul(ratio, scale));\\n }\\n\\n /**********************************************************************************************\\n // calcOutGivenIn //\\n // aO = tokenAmountOut //\\n // bO = tokenBalanceOut //\\n // bI = tokenBalanceIn / / bI \\\\ (wI / wO) \\\\ //\\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\\n // wI = tokenWeightIn \\\\ \\\\ ( bI + ( aI * ( 1 - sF )) / / //\\n // wO = tokenWeightOut //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcOutGivenIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\\n uint256 adjustedIn = bsub(BONE, swapFee);\\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\\n uint256 foo = bpow(y, weightRatio);\\n uint256 bar = bsub(BONE, foo);\\n tokenAmountOut = bmul(tokenBalanceOut, bar);\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcInGivenOut //\\n // aI = tokenAmountIn //\\n // bO = tokenBalanceOut / / bO \\\\ (wO / wI) \\\\ //\\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\\n // aO = tokenAmountOut aI = \\\\ \\\\ ( bO - aO ) / / //\\n // wI = tokenWeightIn -------------------------------------------- //\\n // wO = tokenWeightOut ( 1 - sF ) //\\n // sF = swapFee //\\n **********************************************************************************************/\\n function calcInGivenOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\\n uint256 y = bdiv(tokenBalanceOut, diff);\\n uint256 foo = bpow(y, weightRatio);\\n foo = bsub(foo, BONE);\\n tokenAmountIn = bsub(BONE, swapFee);\\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolOutGivenSingleIn //\\n // pAo = poolAmountOut / \\\\ //\\n // tAi = tokenAmountIn /// / // wI \\\\ \\\\\\\\ \\\\ wI \\\\ //\\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\\\ -- \\\\ //\\n // tW = totalWeight pAo=|| \\\\ \\\\ \\\\\\\\ tW / // | ^ tW | * pS - pS //\\n // tBi = tokenBalanceIn \\\\\\\\ ------------------------------------- / / //\\n // pS = poolSupply \\\\\\\\ tBi / / //\\n // sF = swapFee \\\\ / //\\n **********************************************************************************************/\\n\\n // Charge the trading fee for the proportion of tokenAi\\n /// which is implicitly traded to the other pool tokens.\\n // That proportion is (1- weightTokenIn)\\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\\n\\n function calcPoolOutGivenSingleIn(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\\n\\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\\n\\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n poolAmountOut = bsub(newPoolSupply, poolSupply);\\n return poolAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleInGivenPoolOut //\\n // tAi = tokenAmountIn //(pS + pAo)\\\\ / 1 \\\\\\\\ //\\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\\n // pAo = poolAmountOut \\\\\\\\ pS / \\\\(wI / tW)// //\\n // bI = balanceIn tAi = -------------------------------------------- //\\n // wI = weightIn / wI \\\\ //\\n // tW = totalWeight | 1 - ---- | * sF //\\n // sF = swapFee \\\\ tW / //\\n **********************************************************************************************/\\n function calcSingleInGivenPoolOut(\\n uint256 tokenBalanceIn,\\n uint256 tokenWeightIn,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountIn) {\\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\\n uint256 boo = bdiv(BONE, normalizedWeight);\\n uint256 tokenInRatio = bpow(poolRatio, boo);\\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\\n return tokenAmountIn;\\n }\\n\\n /**********************************************************************************************\\n // calcSingleOutGivenPoolIn //\\n // tAo = tokenAmountOut / / \\\\\\\\ //\\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\\\ / 1 \\\\ \\\\\\\\ //\\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\\n // ps = poolSupply \\\\ \\\\\\\\ pS / \\\\(wO / tW)/ // //\\n // wI = tokenWeightIn tAo = \\\\ \\\\ // //\\n // tW = totalWeight / / wO \\\\ \\\\ //\\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\\n // eF = exitFee \\\\ \\\\ tW / / //\\n **********************************************************************************************/\\n function calcSingleOutGivenPoolIn(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 poolAmountIn,\\n uint256 swapFee\\n ) public pure returns (uint256 tokenAmountOut) {\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n // charge exit fee on the pool token side\\n // pAiAfterExitFee = pAi*(1-exitFee)\\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\\n\\n // newBalTo = poolRatio^(1/weightTo) * balTo;\\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\\n\\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\\n\\n // charge swap fee on the output token side\\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\\n return tokenAmountOut;\\n }\\n\\n /**********************************************************************************************\\n // calcPoolInGivenSingleOut //\\n // pAi = poolAmountIn // / tAo \\\\\\\\ / wO \\\\ \\\\ //\\n // bO = tokenBalanceOut // | bO - -------------------------- |\\\\ | ---- | \\\\ //\\n // tAo = tokenAmountOut pS - || \\\\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\\\ tW / * pS | //\\n // ps = poolSupply \\\\\\\\ -----------------------------------/ / //\\n // wO = tokenWeightOut pAi = \\\\\\\\ bO / / //\\n // tW = totalWeight ------------------------------------------------------------- //\\n // sF = swapFee ( 1 - eF ) //\\n // eF = exitFee //\\n **********************************************************************************************/\\n function calcPoolInGivenSingleOut(\\n uint256 tokenBalanceOut,\\n uint256 tokenWeightOut,\\n uint256 poolSupply,\\n uint256 totalWeight,\\n uint256 tokenAmountOut,\\n uint256 swapFee\\n ) public pure returns (uint256 poolAmountIn) {\\n // charge swap fee on the output token side\\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\\n uint256 zoo = bsub(BONE, normalizedWeight);\\n uint256 zar = bmul(zoo, swapFee);\\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\\n\\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\\n\\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\\n\\n // charge exit fee on the pool token side\\n // pAi = pAiAfterExitFee/(1-exitFee)\\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\\n return poolAmountIn;\\n }\\n}\\n\",\"keccak256\":\"0x0a19a262ccff90637f3d74538bc55cff57d1b9d484df33cca36f29fad8f37e2e\",\"license\":\"MIT\"},\"contracts/balancer/BNum.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BConst.sol\\\";\\n\\ncontract BNum is BConst {\\n function btoi(uint256 a) internal pure returns (uint256) {\\n return a / BONE;\\n }\\n\\n function bfloor(uint256 a) internal pure returns (uint256) {\\n return btoi(a) * BONE;\\n }\\n\\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"ERR_ADD_OVERFLOW\\\");\\n return c;\\n }\\n\\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\\n (uint256 c, bool flag) = bsubSign(a, b);\\n require(!flag, \\\"ERR_SUB_UNDERFLOW\\\");\\n return c;\\n }\\n\\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\\n if (a >= b) {\\n return (a - b, false);\\n } else {\\n return (b - a, true);\\n }\\n }\\n\\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c0 = a * b;\\n require(a == 0 || c0 / a == b, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c1 = c0 + (BONE / 2);\\n require(c1 >= c0, \\\"ERR_MUL_OVERFLOW\\\");\\n uint256 c2 = c1 / BONE;\\n return c2;\\n }\\n\\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b != 0, \\\"ERR_DIV_ZERO\\\");\\n uint256 c0 = a * BONE;\\n require(a == 0 || c0 / a == BONE, \\\"ERR_DIV_INTERNAL\\\"); // bmul overflow\\n uint256 c1 = c0 + (b / 2);\\n require(c1 >= c0, \\\"ERR_DIV_INTERNAL\\\"); // badd require\\n uint256 c2 = c1 / b;\\n return c2;\\n }\\n\\n // DSMath.wpow\\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\\n uint256 z = n % 2 != 0 ? a : BONE;\\n\\n for (n /= 2; n != 0; n /= 2) {\\n a = bmul(a, a);\\n\\n if (n % 2 != 0) {\\n z = bmul(z, a);\\n }\\n }\\n return z;\\n }\\n\\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\\n // of approximation of b^0.w\\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\\n require(base >= MIN_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_LOW\\\");\\n require(base <= MAX_BPOW_BASE, \\\"ERR_BPOW_BASE_TOO_HIGH\\\");\\n\\n uint256 whole = bfloor(exp);\\n uint256 remain = bsub(exp, whole);\\n\\n uint256 wholePow = bpowi(base, btoi(whole));\\n\\n if (remain == 0) {\\n return wholePow;\\n }\\n\\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\\n return bmul(wholePow, partialResult);\\n }\\n\\n function bpowApprox(\\n uint256 base,\\n uint256 exp,\\n uint256 precision\\n ) internal pure returns (uint256) {\\n // term 0:\\n uint256 a = exp;\\n (uint256 x, bool xneg) = bsubSign(base, BONE);\\n uint256 term = BONE;\\n uint256 sum = term;\\n bool negative = false;\\n\\n // term(k) = numer / denom\\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\\n // each iteration, multiply previous term by (a-(k-1)) * x / k\\n // continue until term is less than precision\\n for (uint256 i = 1; term >= precision; i++) {\\n uint256 bigK = i * BONE;\\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\\n term = bmul(term, bmul(c, x));\\n term = bdiv(term, bigK);\\n if (term == 0) break;\\n\\n if (xneg) negative = !negative;\\n if (cneg) negative = !negative;\\n if (negative) {\\n sum = bsub(sum, term);\\n } else {\\n sum = badd(sum, term);\\n }\\n }\\n\\n return sum;\\n }\\n}\\n\",\"keccak256\":\"0x015e4af906575a6fff48089af01a4c683d8e9127179271f545b6e687d767d178\",\"license\":\"MIT\"},\"contracts/balancer/BPool.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BToken.sol\\\";\\nimport \\\"./BMath.sol\\\";\\n\\ncontract BPool is BBronze, BToken, BMath {\\n struct Record {\\n bool bound; // is token bound to pool\\n uint256 index; // private\\n uint256 denorm; // denormalized weight\\n uint256 balance;\\n }\\n\\n event LOG_SWAP(\\n address indexed caller,\\n address indexed tokenIn,\\n address indexed tokenOut,\\n uint256 tokenAmountIn,\\n uint256 tokenAmountOut\\n );\\n\\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\\n\\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\\n\\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\\n\\n modifier _logs_() {\\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\\n _;\\n }\\n\\n modifier _lock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _mutex = true;\\n _;\\n _mutex = false;\\n }\\n\\n modifier _viewlock_() {\\n require(!_mutex, \\\"ERR_REENTRY\\\");\\n _;\\n }\\n\\n bool private _mutex;\\n\\n address private _factory; // BFactory address to push token exitFee to\\n address private _controller; // has CONTROL role\\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\\n\\n // `setSwapFee` and `finalize` require CONTROL\\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\\n uint256 private _swapFee;\\n bool private _finalized;\\n\\n address[] private _tokens;\\n mapping(address => Record) private _records;\\n uint256 private _totalWeight;\\n\\n constructor() {\\n _controller = msg.sender;\\n _factory = msg.sender;\\n _swapFee = MIN_FEE;\\n _publicSwap = false;\\n _finalized = false;\\n }\\n\\n function isPublicSwap() external view returns (bool) {\\n return _publicSwap;\\n }\\n\\n function isFinalized() external view returns (bool) {\\n return _finalized;\\n }\\n\\n function isBound(address t) external view returns (bool) {\\n return _records[t].bound;\\n }\\n\\n function getNumTokens() external view returns (uint256) {\\n return _tokens.length;\\n }\\n\\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\\n return _tokens;\\n }\\n\\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n return _tokens;\\n }\\n\\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].denorm;\\n }\\n\\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\\n return _totalWeight;\\n }\\n\\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n uint256 denorm = _records[token].denorm;\\n return bdiv(denorm, _totalWeight);\\n }\\n\\n function getBalance(address token) external view _viewlock_ returns (uint256) {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n return _records[token].balance;\\n }\\n\\n function getSwapFee() external view _viewlock_ returns (uint256) {\\n return _swapFee;\\n }\\n\\n function getController() external view _viewlock_ returns (address) {\\n return _controller;\\n }\\n\\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(swapFee >= MIN_FEE, \\\"ERR_MIN_FEE\\\");\\n require(swapFee <= MAX_FEE, \\\"ERR_MAX_FEE\\\");\\n _swapFee = swapFee;\\n }\\n\\n function setController(address manager) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _controller = manager;\\n }\\n\\n function setPublicSwap(bool public_) external _logs_ _lock_ {\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n _publicSwap = public_;\\n }\\n\\n function finalize() external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n require(_tokens.length >= MIN_BOUND_TOKENS, \\\"ERR_MIN_TOKENS\\\");\\n\\n _finalized = true;\\n _publicSwap = true;\\n\\n _mintPoolShare(INIT_POOL_SUPPLY);\\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\\n }\\n\\n function bind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n )\\n external\\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\\n {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(!_records[token].bound, \\\"ERR_IS_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(_tokens.length < MAX_BOUND_TOKENS, \\\"ERR_MAX_TOKENS\\\");\\n\\n _records[token] = Record({\\n bound: true,\\n index: _tokens.length,\\n denorm: 0, // balance and denorm will be validated\\n balance: 0 // and set by `rebind`\\n });\\n _tokens.push(token);\\n rebind(token, balance, denorm);\\n }\\n\\n function rebind(\\n address token,\\n uint256 balance,\\n uint256 denorm\\n ) public _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n require(denorm >= MIN_WEIGHT, \\\"ERR_MIN_WEIGHT\\\");\\n require(denorm <= MAX_WEIGHT, \\\"ERR_MAX_WEIGHT\\\");\\n require(balance >= MIN_BALANCE, \\\"ERR_MIN_BALANCE\\\");\\n\\n // Adjust the denorm and totalWeight\\n uint256 oldWeight = _records[token].denorm;\\n if (denorm > oldWeight) {\\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \\\"ERR_MAX_TOTAL_WEIGHT\\\");\\n } else if (denorm < oldWeight) {\\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\\n }\\n _records[token].denorm = denorm;\\n\\n // Adjust the balance record and actual token balance\\n uint256 oldBalance = _records[token].balance;\\n _records[token].balance = balance;\\n if (balance > oldBalance) {\\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\\n } else if (balance < oldBalance) {\\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n }\\n\\n function unbind(address token) external _logs_ _lock_ {\\n require(msg.sender == _controller, \\\"ERR_NOT_CONTROLLER\\\");\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n require(!_finalized, \\\"ERR_IS_FINALIZED\\\");\\n\\n uint256 tokenBalance = _records[token].balance;\\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\\n\\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\\n\\n // Swap the token-to-unbind with the last token,\\n // then delete the last token\\n uint256 index = _records[token].index;\\n uint256 last = _tokens.length - 1;\\n _tokens[index] = _tokens[last];\\n _records[_tokens[index]].index = index;\\n _tokens.pop();\\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\\n\\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\\n _pushUnderlying(token, _factory, tokenExitFee);\\n }\\n\\n // Absorb any tokens that have been sent to this contract into the pool\\n function gulp(address token) external _logs_ _lock_ {\\n require(_records[token].bound, \\\"ERR_NOT_BOUND\\\");\\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\\n }\\n\\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n }\\n\\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\\n external\\n view\\n _viewlock_\\n returns (uint256 spotPrice)\\n {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n Record storage inRecord = _records[tokenIn];\\n Record storage outRecord = _records[tokenOut];\\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\\n }\\n\\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountIn = bmul(ratio, bal);\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountsIn[i], \\\"ERR_LIMIT_IN\\\");\\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\\n _pullUnderlying(t, msg.sender, tokenAmountIn);\\n }\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n }\\n\\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n require(ratio != 0, \\\"ERR_MATH_APPROX\\\");\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _pushPoolShare(_factory, exitFee);\\n _burnPoolShare(pAiAfterExitFee);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n uint256 tokenAmountOut = bmul(ratio, bal);\\n require(tokenAmountOut != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountOut >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\\n _pushUnderlying(t, msg.sender, tokenAmountOut);\\n }\\n }\\n\\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\\n external\\n view\\n returns (uint256[] memory)\\n {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n\\n uint256 poolTotal = totalSupply();\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\\n\\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\\n\\n for (uint256 i = 0; i < _tokens.length; i++) {\\n address t = _tokens[i];\\n uint256 bal = _records[t].balance;\\n\\n _amounts[i] = bmul(ratio, bal);\\n _amounts[_tokens.length + i] = minAmountsOut[i];\\n require(_amounts[i] >= minAmountsOut[i], \\\"ERR_LIMIT_OUT\\\");\\n }\\n\\n return _amounts;\\n }\\n\\n function swapExactAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n address tokenOut,\\n uint256 minAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountOut = calcOutGivenIn(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountIn,\\n _swapFee\\n );\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountOut, spotPriceAfter);\\n }\\n\\n function swapExactAmountOut(\\n address tokenIn,\\n uint256 maxAmountIn,\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPrice\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(_publicSwap, \\\"ERR_SWAP_NOT_PUBLIC\\\");\\n\\n Record storage inRecord = _records[address(tokenIn)];\\n Record storage outRecord = _records[address(tokenOut)];\\n\\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n uint256 spotPriceBefore =\\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\\n require(spotPriceBefore <= maxPrice, \\\"ERR_BAD_LIMIT_PRICE\\\");\\n\\n tokenAmountIn = calcInGivenOut(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n tokenAmountOut,\\n _swapFee\\n );\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n spotPriceAfter = calcSpotPrice(\\n inRecord.balance,\\n inRecord.denorm,\\n outRecord.balance,\\n outRecord.denorm,\\n _swapFee\\n );\\n require(spotPriceAfter >= spotPriceBefore, \\\"ERR_MATH_APPROX\\\");\\n require(spotPriceAfter <= maxPrice, \\\"ERR_LIMIT_PRICE\\\");\\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \\\"ERR_MATH_APPROX\\\");\\n\\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\\n\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return (tokenAmountIn, spotPriceAfter);\\n }\\n\\n function joinswapExternAmountIn(\\n address tokenIn,\\n uint256 tokenAmountIn,\\n uint256 minPoolAmountOut\\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n poolAmountOut = calcPoolOutGivenSingleIn(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountIn,\\n _swapFee\\n );\\n\\n require(poolAmountOut >= minPoolAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return poolAmountOut;\\n }\\n\\n function joinswapPoolAmountOut(\\n address tokenIn,\\n uint256 poolAmountOut,\\n uint256 maxAmountIn\\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenIn].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage inRecord = _records[tokenIn];\\n\\n tokenAmountIn = calcSingleInGivenPoolOut(\\n inRecord.balance,\\n inRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountOut,\\n _swapFee\\n );\\n\\n require(tokenAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(tokenAmountIn <= maxAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \\\"ERR_MAX_IN_RATIO\\\");\\n\\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\\n\\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\\n\\n _mintPoolShare(poolAmountOut);\\n _pushPoolShare(msg.sender, poolAmountOut);\\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\\n\\n return tokenAmountIn;\\n }\\n\\n function exitswapPoolAmountIn(\\n address tokenOut,\\n uint256 poolAmountIn,\\n uint256 minAmountOut\\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n tokenAmountOut = calcSingleOutGivenPoolIn(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n poolAmountIn,\\n _swapFee\\n );\\n\\n require(tokenAmountOut >= minAmountOut, \\\"ERR_LIMIT_OUT\\\");\\n\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return tokenAmountOut;\\n }\\n\\n function exitswapExternAmountOut(\\n address tokenOut,\\n uint256 tokenAmountOut,\\n uint256 maxPoolAmountIn\\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\\n require(_finalized, \\\"ERR_NOT_FINALIZED\\\");\\n require(_records[tokenOut].bound, \\\"ERR_NOT_BOUND\\\");\\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \\\"ERR_MAX_OUT_RATIO\\\");\\n\\n Record storage outRecord = _records[tokenOut];\\n\\n poolAmountIn = calcPoolInGivenSingleOut(\\n outRecord.balance,\\n outRecord.denorm,\\n _totalSupply,\\n _totalWeight,\\n tokenAmountOut,\\n _swapFee\\n );\\n\\n require(poolAmountIn != 0, \\\"ERR_MATH_APPROX\\\");\\n require(poolAmountIn <= maxPoolAmountIn, \\\"ERR_LIMIT_IN\\\");\\n\\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\\n\\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\\n\\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\\n\\n _pullPoolShare(msg.sender, poolAmountIn);\\n _burnPoolShare(bsub(poolAmountIn, exitFee));\\n _pushPoolShare(_factory, exitFee);\\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\\n\\n return poolAmountIn;\\n }\\n\\n // ==\\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\\n // You must `_lock_` or otherwise ensure reentry-safety\\n\\n function _pullUnderlying(\\n address erc20,\\n address from,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pushUnderlying(\\n address erc20,\\n address to,\\n uint256 amount\\n ) internal {\\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\\n require(xfer, \\\"ERR_ERC20_FALSE\\\");\\n }\\n\\n function _pullPoolShare(address from, uint256 amount) internal {\\n _pull(from, amount);\\n }\\n\\n function _pushPoolShare(address to, uint256 amount) internal {\\n _push(to, amount);\\n }\\n\\n function _mintPoolShare(uint256 amount) internal {\\n _mint(amount);\\n }\\n\\n function _burnPoolShare(uint256 amount) internal {\\n _burn(amount);\\n }\\n}\\n\",\"keccak256\":\"0x776103e689b42b4ab375106ed1183fd14fc7b842ff4eaff52de716cdb1689d92\",\"license\":\"MIT\"},\"contracts/balancer/BToken.sol\":{\"content\":\"// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program. If not, see .\\n\\n// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./BNum.sol\\\";\\n\\ninterface IERC20Balancer {\\n function totalSupply() external view returns (uint256);\\n\\n function balanceOf(address whom) external view returns (uint256);\\n\\n function allowance(address src, address dst) external view returns (uint256);\\n\\n function approve(address dst, uint256 amt) external returns (bool);\\n\\n function transfer(address dst, uint256 amt) external returns (bool);\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external returns (bool);\\n}\\n\\ncontract BTokenBase is BNum {\\n mapping(address => uint256) internal _balance;\\n mapping(address => mapping(address => uint256)) internal _allowance;\\n uint256 internal _totalSupply;\\n\\n event Approval(address indexed src, address indexed dst, uint256 amt);\\n event Transfer(address indexed src, address indexed dst, uint256 amt);\\n\\n function _mint(uint256 amt) internal {\\n _balance[address(this)] = badd(_balance[address(this)], amt);\\n _totalSupply = badd(_totalSupply, amt);\\n emit Transfer(address(0), address(this), amt);\\n }\\n\\n function _burn(uint256 amt) internal {\\n require(_balance[address(this)] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[address(this)] = bsub(_balance[address(this)], amt);\\n _totalSupply = bsub(_totalSupply, amt);\\n emit Transfer(address(this), address(0), amt);\\n }\\n\\n function _move(\\n address src,\\n address dst,\\n uint256 amt\\n ) internal {\\n require(_balance[src] >= amt, \\\"ERR_INSUFFICIENT_BAL\\\");\\n _balance[src] = bsub(_balance[src], amt);\\n _balance[dst] = badd(_balance[dst], amt);\\n emit Transfer(src, dst, amt);\\n }\\n\\n function _push(address to, uint256 amt) internal {\\n _move(address(this), to, amt);\\n }\\n\\n function _pull(address from, uint256 amt) internal {\\n _move(from, address(this), amt);\\n }\\n}\\n\\ncontract BToken is BTokenBase, IERC20Balancer {\\n string private _name = \\\"Balancer Pool Token\\\";\\n string private _symbol = \\\"BPT\\\";\\n uint8 private _decimals = 18;\\n\\n function name() public view returns (string memory) {\\n return _name;\\n }\\n\\n function symbol() public view returns (string memory) {\\n return _symbol;\\n }\\n\\n function decimals() public view returns (uint8) {\\n return _decimals;\\n }\\n\\n function allowance(address src, address dst) external view override returns (uint256) {\\n return _allowance[src][dst];\\n }\\n\\n function balanceOf(address whom) external view override returns (uint256) {\\n return _balance[whom];\\n }\\n\\n function totalSupply() public view override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n function approve(address dst, uint256 amt) external override returns (bool) {\\n _allowance[msg.sender][dst] = amt;\\n emit Approval(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\\n uint256 oldValue = _allowance[msg.sender][dst];\\n if (amt > oldValue) {\\n _allowance[msg.sender][dst] = 0;\\n } else {\\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\\n }\\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\\n return true;\\n }\\n\\n function transfer(address dst, uint256 amt) external override returns (bool) {\\n _move(msg.sender, dst, amt);\\n return true;\\n }\\n\\n function transferFrom(\\n address src,\\n address dst,\\n uint256 amt\\n ) external override returns (bool) {\\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \\\"ERR_BTOKEN_BAD_CALLER\\\");\\n _move(src, dst, amt);\\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\\n }\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x96a133234ad4896507bb420719cd57c33b17499c87558016adc9fc1b30d78eca\",\"license\":\"MIT\"},\"contracts/libraries/CalculateLinesToBPoolOdds.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./SafeMathUint256.sol\\\";\\nimport \\\"./SafeMathInt256.sol\\\";\\n\\nabstract contract CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\\n\\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\\n uint256 _total = sum(_proportions);\\n\\n _odds = new uint256[](_proportions.length);\\n for (uint256 i = 0; i < _proportions.length; i++) {\\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\\n require(_odds[i] >= 1e18, \\\"min outcome weight is 2%\\\");\\n }\\n }\\n\\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\\n for (uint256 i = 0; i < _numbers.length; i++) {\\n _sum += _numbers[i];\\n }\\n }\\n\\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\\n _odds = new uint256[](_size);\\n\\n if (_invalid) _odds[0] = 1e18; // 2%\\n\\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\\n _odds[i] = _each;\\n }\\n }\\n\\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\\n\\n uint256 _total = _odds1 + _odds2;\\n\\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\\n\\n // Moneyline odds are too skewed: would have under 2% odds.\\n require(_odds1 >= 1e18);\\n require(_odds2 >= 1e18);\\n\\n _odds = new uint256[](3);\\n _odds[0] = 1e18; // Invalid, 2%\\n _odds[1] = _odds1;\\n _odds[2] = _odds2;\\n }\\n\\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\\n if (_line < 0) {\\n // favored\\n uint256 _posLine = uint256(-_line);\\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\\n } else {\\n // underdog\\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83e6eb562ea996e8bf34b6e9b5ac854e2be240f420a33b9c3612401e040f069\",\"license\":\"MIT\"},\"contracts/libraries/HasHeadToHeadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasHeadToHeadMarket is\\n AbstractMarketFactoryV3,\\n Sport,\\n CalculateLinesToBPoolOdds,\\n TokenNamesFromTeams\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private headToHeadMarketType;\\n string private noContestName;\\n\\n uint256 constant HeadToHeadAway = 1;\\n uint256 constant HeadToHeadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n headToHeadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeHeadToHeadMarket(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256) {\\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\\n return\\n makeSportsMarket(\\n noContestName,\\n _homeTeamName,\\n _awayTeamName,\\n oddsFromLines(_moneylines[1], _moneylines[0])\\n );\\n }\\n\\n function resolveHeadToHeadMarket(\\n uint256 _marketId,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\\n if (_homeScore > _awayScore) {\\n return HeadToHeadHome;\\n } else if (_homeScore < _awayScore) {\\n return HeadToHeadAway;\\n } else {\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x46fa1c3208b0c295c1a0e7eb1b1835bbfccbe3a9d6faba7bda51f231f7f83616\",\"license\":\"MIT\"},\"contracts/libraries/HasOverUnderMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\n\\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private overUnderMarketType;\\n string private noContestName;\\n\\n uint256 constant Over = 1;\\n uint256 constant Under = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n overUnderMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeOverUnderMarket() internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\\n }\\n\\n function resolveOverUnderMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcOverUnderWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetTotal\\n ) internal pure returns (uint256) {\\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\\n\\n if (_actualTotal > _targetTotal) {\\n return Over; // total score above than line\\n } else if (_actualTotal < _targetTotal) {\\n return Under; // total score below line\\n } else {\\n return NoContest; // draw / tie; some sports eliminate this with half-points\\n }\\n }\\n\\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Over] = \\\"Over\\\";\\n _names[Under] = \\\"Under\\\";\\n }\\n}\\n\",\"keccak256\":\"0x6c183c99c90080bd600b5b511f954ba18e605cd3348bb08785e06413d22e8081\",\"license\":\"MIT\"},\"contracts/libraries/HasSpreadMarket.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./CalculateLinesToBPoolOdds.sol\\\";\\nimport \\\"./TokenNamesFromTeams.sol\\\";\\n\\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 private spreadMarketType;\\n string private noContestName;\\n\\n uint256 constant SpreadAway = 1;\\n uint256 constant SpreadHome = 2;\\n\\n constructor(uint256 _marketType, string memory _noContestName) {\\n spreadMarketType = _marketType;\\n noContestName = _noContestName;\\n }\\n\\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\\n }\\n\\n function resolveSpreadMarket(\\n uint256 _marketId,\\n int256 _line,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal {\\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\\n endMarket(_marketId, _shareTokenIndex);\\n }\\n\\n function calcSpreadWinner(\\n uint256 _homeScore,\\n uint256 _awayScore,\\n int256 _targetSpread\\n ) internal pure returns (uint256) {\\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\\n\\n if (_adjustedHomeScore > int256(_awayScore)) {\\n return SpreadHome; // home spread greater\\n } else if (_adjustedHomeScore < int256(_awayScore)) {\\n return SpreadAway; // away spread lesser\\n } else {\\n // draw / tie; some sports eliminate this with half-points\\n return NoContest;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe1edc04752dd0b15cb59937aaa08add6f4daf3def81e2c542c3b5e6b83af78b4\",\"license\":\"MIT\"},\"contracts/libraries/IERC20Full.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IERC20Full is IERC20 {\\n function name() external view returns (string memory);\\n\\n function symbol() external view returns (string memory);\\n\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x228083482ab7326cdb12ae8cb7dcd8d3b805651e35c08c29a7b0a54e0e97fbb0\",\"license\":\"MIT\"},\"contracts/libraries/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\ninterface IOwnable {\\n function getOwner() external view returns (address);\\n\\n function transferOwnership(address _newOwner) external returns (bool);\\n}\\n\",\"keccak256\":\"0xace52430f7fd5468e14cb5a8f91f66daa9518d8393b257a3d01c5899d4828000\",\"license\":\"MIT\"},\"contracts/libraries/LineHelper.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract LineHelper {\\n function build1Line() internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](1);\\n }\\n\\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\\n _lines = new int256[](3);\\n // 0 is the Head-to-Head market, which has no lines\\n _lines[1] = addHalfPoint(_homeSpread);\\n _lines[2] = addHalfPoint(_totalScore);\\n }\\n\\n function addHalfPoint(int256 _line) internal pure returns (int256) {\\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\\n if (_line >= 0 && _line % 10 == 0) {\\n return _line + 5;\\n } else if (_line < 0 && (-_line) % 10 == 0) {\\n return _line - 5;\\n } else {\\n return _line;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x92fd5087f0426ed52f882c7f3ef6d8ed2446dfc7cee9098e29313baaed27875b\",\"license\":\"MIT\"},\"contracts/libraries/ManagedByLink.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./Ownable.sol\\\";\\n\\nabstract contract ManagedByLink is Ownable {\\n event LinkNodeChanged(address newLinkNode);\\n\\n address public linkNode;\\n\\n constructor(address _linkNode) {\\n linkNode = _linkNode;\\n }\\n\\n function setLinkNode(address _newLinkNode) external onlyOwner {\\n linkNode = _newLinkNode;\\n emit LinkNodeChanged(_newLinkNode);\\n }\\n\\n modifier onlyLinkNode() {\\n require(msg.sender == linkNode);\\n _;\\n }\\n}\\n\",\"keccak256\":\"0x816d86e19e2473e442d8e63e38c53ea40c0ac8a5cef22232de184690f82e2e8c\",\"license\":\"MIT\"},\"contracts/libraries/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"./IOwnable.sol\\\";\\n\\n/**\\n * @title Ownable\\n * @dev The Ownable contract has an owner address, and provides basic authorization control\\n * functions, this simplifies the implementation of \\\"user permissions\\\".\\n */\\nabstract contract Ownable is IOwnable {\\n address internal owner;\\n\\n /**\\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\\n * account.\\n */\\n constructor() {\\n owner = msg.sender;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(msg.sender == owner);\\n _;\\n }\\n\\n function getOwner() public view override returns (address) {\\n return owner;\\n }\\n\\n /**\\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\\n * @param _newOwner The address to transfer ownership to.\\n */\\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\\n require(_newOwner != address(0));\\n onTransferOwnership(owner, _newOwner);\\n owner = _newOwner;\\n return true;\\n }\\n\\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\\n function onTransferOwnership(address, address) internal virtual;\\n}\\n\",\"keccak256\":\"0x65f237e09612478773b06aa74b21364f4ae25b6c419793be79ab9aa0258e57ef\",\"license\":\"MIT\"},\"contracts/libraries/ResolveByScore.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\nimport \\\"./ManagedByLink.sol\\\";\\n\\nabstract contract ResolvesByScore is Sport, ManagedByLink {\\n function resolveEvent(\\n uint256 _eventId,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId, // for verifying team stability\\n uint256 _awayTeamId, // for verifying team stability\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) public onlyLinkNode {\\n SportsEvent storage _event = sportsEvents[_eventId];\\n\\n require(_event.status == SportsEventStatus.Scheduled);\\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\\n\\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\\n resolveInvalidEvent(_eventId);\\n } else {\\n resolveValidEvent(_event, _homeScore, _awayScore);\\n }\\n\\n _event.status = _eventStatus;\\n _event.homeScore = _homeScore;\\n _event.awayScore = _awayScore;\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal virtual;\\n}\\n\",\"keccak256\":\"0x8c79469cf454f2852d483dcfd46ea627da6924e40fd57ed376c45d7d97113cb8\",\"license\":\"MIT\"},\"contracts/libraries/Rewardable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Rewardable {\\n // Rewards will be paid out over the lifetime of an event.\\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\\n\\n // _Id here is the market id passed to the amm factory when creating a pool.\\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xacc970c6952f38f8306e1289e99fa85a163b3fe9c2c1923f11eb3c519dce9ddb\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathInt256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathInt256\\n * @dev Int256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathInt256 {\\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\\n int256 private constant INT256_MIN = -2**(255);\\n int256 private constant INT256_MAX = (2**(255) - 1);\\n\\n function mul(int256 a, int256 b) internal pure returns (int256) {\\n int256 c = a * b;\\n require(a == 0 || c / a == b);\\n return c;\\n }\\n\\n function div(int256 a, int256 b) internal pure returns (int256) {\\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\\n int256 c = a / b;\\n return c;\\n }\\n\\n function sub(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\\n return a - b;\\n }\\n\\n function add(int256 a, int256 b) internal pure returns (int256) {\\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\\n return a + b;\\n }\\n\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function abs(int256 a) internal pure returns (int256) {\\n if (a < 0) {\\n return -a;\\n }\\n return a;\\n }\\n\\n function getInt256Min() internal pure returns (int256) {\\n return INT256_MIN;\\n }\\n\\n function getInt256Max() internal pure returns (int256) {\\n return INT256_MAX;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n int256 a,\\n int256 b,\\n int256 base\\n ) internal pure returns (int256) {\\n return div(mul(a, base), b);\\n }\\n\\n function sqrt(int256 y) internal pure returns (int256 z) {\\n if (y > 3) {\\n int256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n}\\n\",\"keccak256\":\"0x714309025fa79f257ce215aca9bd5bd2b4c1cc5b4e14579fb815da218f8350a5\",\"license\":\"MIT\"},\"contracts/libraries/SafeMathUint256.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\n/**\\n * @title SafeMathUint256\\n * @dev Uint256 math operations with safety checks that throw on error\\n */\\nlibrary SafeMathUint256 {\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b);\\n\\n return c;\\n }\\n\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n // assert(b > 0); // Solidity automatically throws when dividing by 0\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n return c;\\n }\\n\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n require(b <= a);\\n return a - b;\\n }\\n\\n function subS(\\n uint256 a,\\n uint256 b,\\n string memory message\\n ) internal pure returns (uint256) {\\n require(b <= a, message);\\n return a - b;\\n }\\n\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a);\\n return c;\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a <= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (a >= b) {\\n return a;\\n } else {\\n return b;\\n }\\n }\\n\\n function sqrt(uint256 y) internal pure returns (uint256 z) {\\n if (y > 3) {\\n uint256 x = (y + 1) / 2;\\n z = y;\\n while (x < z) {\\n z = x;\\n x = (y / x + x) / 2;\\n }\\n } else if (y != 0) {\\n z = 1;\\n }\\n }\\n\\n function getUint256Min() internal pure returns (uint256) {\\n return 0;\\n }\\n\\n function getUint256Max() internal pure returns (uint256) {\\n // 2 ** 256 - 1\\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\\n }\\n\\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\\n return a % b == 0;\\n }\\n\\n // Float [fixed point] Operations\\n function fxpMul(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, b), base);\\n }\\n\\n function fxpDiv(\\n uint256 a,\\n uint256 b,\\n uint256 base\\n ) internal pure returns (uint256) {\\n return div(mul(a, base), b);\\n }\\n}\\n\",\"keccak256\":\"0x96f8c0fa44dfb1d34495acebab8f6385d50a34132bd28b02a6589a976f869a87\",\"license\":\"MIT\"},\"contracts/libraries/Sport.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../turbo/AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./LineHelper.sol\\\";\\n\\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\\n event SportsEventCreated(\\n uint256 id,\\n uint256[] markets,\\n int256[] lines,\\n uint256 homeTeamId,\\n uint256 awayTeamId,\\n string homeTeamName,\\n string awayTeamName,\\n uint256 estimatedStartTime\\n );\\n\\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\\n struct SportsEvent {\\n SportsEventStatus status;\\n uint256[] markets;\\n int256[] lines;\\n uint256 estimatedStartTime;\\n uint256 homeTeamId;\\n uint256 awayTeamId;\\n string homeTeamName;\\n string awayTeamName;\\n uint256 homeScore;\\n uint256 awayScore;\\n }\\n // EventId => EventDetails\\n mapping(uint256 => SportsEvent) public sportsEvents;\\n uint256[] public listOfSportsEvents;\\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\\n uint256 constant NoContest = 0;\\n\\n function eventCount() public view returns (uint256) {\\n return listOfSportsEvents.length;\\n }\\n\\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\\n return sportsEvents[_eventId];\\n }\\n\\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\\n _eventId = listOfSportsEvents[_index];\\n _event = getSportsEvent(_eventId);\\n }\\n\\n function makeSportsEvent(\\n uint256 _eventId,\\n uint256[] memory _markets,\\n int256[] memory _lines,\\n uint256 _estimatedStartTime,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal {\\n // Cannot create markets for an event twice.\\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \\\"event exists\\\");\\n\\n for (uint256 i = 0; i < _markets.length; i++) {\\n marketIdToEventIdMapping[_markets[i]] = _eventId;\\n }\\n\\n listOfSportsEvents.push(_eventId);\\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\\n sportsEvents[_eventId].markets = _markets;\\n sportsEvents[_eventId].lines = _lines;\\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\\n // homeScore and awayScore default to zero, which is correct for new events\\n\\n emit SportsEventCreated(\\n _eventId,\\n _markets,\\n _lines,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName,\\n _estimatedStartTime\\n );\\n }\\n\\n uint256 constant WhoWonUnknown = 0;\\n uint256 constant WhoWonHome = 1;\\n uint256 constant WhoWonAway = 2;\\n uint256 constant WhoWonDraw = 3;\\n\\n function eventIsNoContest(\\n SportsEvent memory _event,\\n SportsEventStatus _eventStatus,\\n uint256 _homeTeamId,\\n uint256 _awayTeamId,\\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\\n ) internal pure returns (bool) {\\n bool _draw = _whoWon == WhoWonDraw;\\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\\n }\\n\\n function resolveInvalidEvent(uint256 _eventId) internal {\\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\\n for (uint256 i = 0; i < _marketIds.length; i++) {\\n uint256 _marketId = _marketIds[i];\\n if (_marketId == 0) continue; // skip non-created markets\\n endMarket(_marketId, NoContest);\\n }\\n }\\n\\n // TODO is this needed? getSportsEvent should do the same\\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\\n uint256[] storage _original = sportsEvents[_eventId].markets;\\n uint256 _len = _original.length;\\n _markets = new uint256[](_len);\\n for (uint256 i = 0; i < _len; i++) {\\n _markets[i] = _original[i];\\n }\\n }\\n\\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\\n return getSportsEvent(_eventId).estimatedStartTime;\\n }\\n}\\n\\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\\nabstract contract SportView is Sport {\\n // Only usable off-chain. Gas cost can easily eclipse block limit.\\n // Lists all events that could be resolved with a call to resolveEvent.\\n // Not all will be resolvable because this does not ensure the game ended.\\n function listResolvableEvents() external view returns (uint256[] memory) {\\n uint256 _totalResolvable = countResolvableEvents();\\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\\n\\n uint256 n = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n if (n > _totalResolvable) break;\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _resolvableEvents[n] = _eventId;\\n n++;\\n }\\n }\\n\\n return _resolvableEvents;\\n }\\n\\n function countResolvableEvents() internal view returns (uint256) {\\n uint256 _totalResolvable = 0;\\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\\n uint256 _eventId = listOfSportsEvents[i];\\n if (isEventResolvable(_eventId)) {\\n _totalResolvable++;\\n }\\n }\\n return _totalResolvable;\\n }\\n\\n // Returns true if a call to resolveEvent is potentially useful.\\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\\n uint256[] memory _markets = getEventMarkets(_eventId);\\n\\n bool _unresolved = false; // default because non-existing markets aren't resolvable\\n for (uint256 i = 0; i < _markets.length; i++) {\\n uint256 _marketId = _markets[i];\\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\\n _unresolved = true;\\n break;\\n }\\n }\\n\\n return _unresolved;\\n }\\n}\\n\",\"keccak256\":\"0x148d3445203660ed0995865eec47cbfd74af63234f3e20c37db3f1d663beee63\",\"license\":\"MIT\"},\"contracts/libraries/TokenNamesFromTeams.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./Sport.sol\\\";\\n\\nabstract contract TokenNamesFromTeams is Sport {\\n uint256 constant Away = 1;\\n uint256 constant Home = 2;\\n\\n function makeSportsMarket(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName,\\n uint256[] memory _odds\\n ) internal returns (uint256) {\\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\\n return startMarket(msg.sender, _outcomeNames, _odds, true);\\n }\\n\\n function makeOutcomeNames(\\n string memory _noContestName,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) private pure returns (string[] memory _names) {\\n _names = new string[](3);\\n _names[NoContest] = _noContestName;\\n _names[Away] = _awayTeamName;\\n _names[Home] = _homeTeamName;\\n }\\n}\\n\",\"keccak256\":\"0xe877135430b2e5d6bc9694e78ac4aab9fa1249ecd1f90b1134d180b4e43a5727\",\"license\":\"MIT\"},\"contracts/libraries/Versioned.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nabstract contract Versioned {\\n string internal version;\\n\\n constructor(string memory _version) {\\n version = _version;\\n }\\n\\n function getVersion() public view returns (string memory) {\\n return version;\\n }\\n}\\n\",\"keccak256\":\"0x06500e2a2aefc31595428cc6eb2b0d601fe853d316a41f53621ac8b809441c5f\",\"license\":\"MIT\"},\"contracts/turbo/AbstractMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./TurboShareTokenFactory.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/Rewardable.sol\\\";\\n\\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\\n using SafeMathUint256 for uint256;\\n\\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\\n event MarketActivated(uint256 id);\\n\\n event SharesMinted(uint256 id, uint256 amount, address receiver);\\n event SharesBurned(uint256 id, uint256 amount, address receiver);\\n event WinningsClaimed(\\n uint256 id,\\n address winningOutcome,\\n uint256 winningIndex,\\n string winningName,\\n uint256 amount,\\n uint256 settlementFee,\\n uint256 payout,\\n address indexed receiver\\n );\\n\\n IERC20Full public collateral;\\n FeePot public feePot;\\n\\n // fees are out of 1e18 and only apply to new markets\\n uint256 public stakerFee;\\n uint256 public settlementFee;\\n uint256 public protocolFee;\\n\\n address public protocol; // collects protocol fees\\n\\n uint256 public accumulatedProtocolFee = 0;\\n // settlement address => amount of collateral\\n mapping(address => uint256) public accumulatedSettlementFees;\\n\\n // How many shares equals one collateral.\\n // Necessary to account for math errors from small numbers in balancer.\\n // shares = collateral / shareFactor\\n // collateral = shares * shareFactor\\n uint256 public shareFactor;\\n\\n struct Market {\\n address settlementAddress;\\n OwnedERC20[] shareTokens;\\n OwnedERC20 winner;\\n uint256 winnerIndex;\\n uint256 settlementFee;\\n uint256 protocolFee;\\n uint256 stakerFee;\\n uint256 creationTimestamp;\\n uint256 resolutionTimestamp; // when winner is declared\\n uint256[] initialOdds;\\n bool active; // false if not ready to use or if resolved\\n }\\n Market[] internal markets;\\n\\n uint256 private constant MAX_UINT = 2**256 - 1;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees, // staker, settlement, protocol\\n address _protocol\\n ) {\\n owner = _owner; // controls fees for new markets\\n collateral = _collateral;\\n shareFactor = _shareFactor;\\n feePot = _feePot;\\n stakerFee = _fees[0];\\n settlementFee = _fees[1];\\n protocolFee = _fees[2];\\n protocol = _protocol;\\n\\n _collateral.approve(address(_feePot), MAX_UINT);\\n\\n // First market is always empty so that marketid zero means \\\"no market\\\"\\n markets.push(makeEmptyMarket());\\n }\\n\\n // Returns an empty struct if the market doesn't exist.\\n // Can check market existence before calling this by comparing _id against markets.length.\\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\\n function getMarket(uint256 _id) public view returns (Market memory) {\\n if (_id >= markets.length) {\\n return makeEmptyMarket();\\n } else {\\n return markets[_id];\\n }\\n }\\n\\n function marketCount() public view returns (uint256) {\\n return markets.length;\\n }\\n\\n // Returns factory-specific details about a market.\\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\\n\\n function mintShares(\\n uint256 _id,\\n uint256 _shareToMint,\\n address _receiver\\n ) public {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n uint256 _cost = calcCost(_shareToMint);\\n collateral.transferFrom(msg.sender, address(this), _cost);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\\n }\\n\\n emit SharesMinted(_id, _shareToMint, _receiver);\\n }\\n\\n function burnShares(\\n uint256 _id,\\n uint256 _sharesToBurn,\\n address _receiver\\n ) public returns (uint256) {\\n require(markets.length > _id);\\n require(markets[_id].active);\\n\\n Market memory _market = markets[_id];\\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\\n // errors if sender doesn't have enough shares\\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\\n }\\n\\n uint256 _payout = calcCost(_sharesToBurn);\\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\\n\\n accumulatedProtocolFee += _protocolFee;\\n collateral.transfer(_receiver, _payout);\\n feePot.depositFees(_stakerFee);\\n\\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\\n return _payout;\\n }\\n\\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\\n require(isMarketResolved(_id), \\\"market unresolved\\\");\\n\\n Market memory _market = markets[_id];\\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\\n\\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\\n _payout = _payout.sub(_settlementFee);\\n\\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\\n collateral.transfer(_receiver, _payout);\\n\\n uint256 _winningIndex = _market.winnerIndex;\\n string memory _winningName = _market.winner.name();\\n\\n emit WinningsClaimed(\\n _id,\\n address(_market.winner),\\n _winningIndex,\\n _winningName,\\n _winningShares,\\n _settlementFee,\\n _payout,\\n _receiver\\n );\\n return _payout;\\n }\\n\\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\\n uint256 _totalWinnings = 0;\\n for (uint256 i = 0; i < _ids.length; i++) {\\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\\n }\\n return _totalWinnings;\\n }\\n\\n function claimSettlementFees(address _receiver) public returns (uint256) {\\n uint256 _fees = accumulatedSettlementFees[msg.sender];\\n if (_fees > 0) {\\n accumulatedSettlementFees[msg.sender] = 0;\\n collateral.transfer(_receiver, _fees);\\n }\\n return _fees;\\n }\\n\\n function claimProtocolFees() public returns (uint256) {\\n require(msg.sender == protocol || msg.sender == address(this));\\n uint256 _fees = accumulatedProtocolFee;\\n if (_fees > 0) {\\n accumulatedProtocolFee = 0;\\n collateral.transfer(protocol, _fees);\\n }\\n return _fees;\\n }\\n\\n function setSettlementFee(uint256 _newFee) external onlyOwner {\\n settlementFee = _newFee;\\n }\\n\\n function setStakerFee(uint256 _newFee) external onlyOwner {\\n stakerFee = _newFee;\\n }\\n\\n function setProtocolFee(uint256 _newFee) external onlyOwner {\\n protocolFee = _newFee;\\n }\\n\\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\\n if (_claimFirst) {\\n claimProtocolFees();\\n }\\n protocol = _newProtocol;\\n }\\n\\n function startMarket(\\n address _settlementAddress,\\n string[] memory _names,\\n uint256[] memory _initialOdds,\\n bool _active\\n ) internal returns (uint256 _marketId) {\\n _marketId = markets.length;\\n markets.push(\\n Market(\\n _settlementAddress,\\n createShareTokens(_names, address(this)),\\n OwnedERC20(0),\\n 0,\\n settlementFee,\\n protocolFee,\\n stakerFee,\\n block.timestamp,\\n 0,\\n _initialOdds,\\n _active\\n )\\n );\\n emit MarketCreated(_marketId, _names, _initialOdds);\\n if (_active) {\\n emit MarketActivated(_marketId);\\n }\\n }\\n\\n function activateMarket(uint256 _marketId) internal {\\n markets[_marketId].active = true;\\n emit MarketActivated(_marketId);\\n }\\n\\n function makeEmptyMarket() private pure returns (Market memory) {\\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\\n uint256[] memory _initialOdds = new uint256[](0);\\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\\n }\\n\\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\\n Market storage _market = markets[_marketId];\\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\\n\\n _market.winner = _winner;\\n _market.active = false;\\n _market.winnerIndex = _winningOutcome;\\n _market.resolutionTimestamp = block.timestamp;\\n string memory _outcomeName = _winner.name();\\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\\n }\\n\\n function isMarketResolved(uint256 _id) public view returns (bool) {\\n Market memory _market = markets[_id];\\n return _market.winner != OwnedERC20(0);\\n }\\n\\n // shares => collateral\\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\\n function calcCost(uint256 _shares) public view returns (uint256) {\\n require(_shares >= shareFactor && _shares % shareFactor == 0);\\n return _shares / shareFactor;\\n }\\n\\n // collateral => shares\\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\\n return _collateralIn * shareFactor;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x05942ebd5473a1b666eb76f180c143a3f8460e678c8f52edf1454607f0721962\",\"license\":\"MIT\"},\"contracts/turbo/FeePot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/SafeMathUint256.sol\\\";\\nimport \\\"../libraries/IERC20Full.sol\\\";\\n\\ncontract FeePot is ERC20 {\\n using SafeMathUint256 for uint256;\\n\\n uint256 internal constant magnitude = 2**128;\\n\\n IERC20Full public collateral;\\n IERC20Full public reputationToken;\\n\\n uint256 public magnifiedFeesPerShare;\\n\\n mapping(address => uint256) public magnifiedFeesCorrections;\\n mapping(address => uint256) public storedFees;\\n\\n uint256 public feeReserve;\\n\\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\\n ERC20(\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol())),\\n string(abi.encodePacked(\\\"S_\\\", _reputationToken.symbol()))\\n )\\n {\\n collateral = _collateral;\\n reputationToken = _reputationToken;\\n\\n require(_collateral != IERC20Full(0));\\n }\\n\\n function depositFees(uint256 _amount) public returns (bool) {\\n collateral.transferFrom(msg.sender, address(this), _amount);\\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\\n if (_totalSupply == 0) {\\n feeReserve = feeReserve.add(_amount);\\n return true;\\n }\\n if (feeReserve > 0) {\\n _amount = _amount.add(feeReserve);\\n feeReserve = 0;\\n }\\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\\n return true;\\n }\\n\\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\\n return earnedFeesOf(_owner).add(storedFees[_owner]);\\n }\\n\\n function earnedFeesOf(address _owner) public view returns (uint256) {\\n uint256 _ownerBalance = balanceOf(_owner);\\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\\n }\\n\\n function _transfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) internal override {\\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\\n super._transfer(_from, _to, _amount);\\n\\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\\n }\\n\\n function stake(uint256 _amount) external returns (bool) {\\n reputationToken.transferFrom(msg.sender, address(this), _amount);\\n _mint(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\\n magnifiedFeesPerShare.mul(_amount)\\n );\\n return true;\\n }\\n\\n function exit(uint256 _amount) external returns (bool) {\\n redeemInternal(msg.sender);\\n _burn(msg.sender, _amount);\\n reputationToken.transfer(msg.sender, _amount);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeem() public returns (bool) {\\n redeemInternal(msg.sender);\\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\\n return true;\\n }\\n\\n function redeemInternal(address _account) internal {\\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\\n if (_withdrawableFees > 0) {\\n storedFees[_account] = 0;\\n collateral.transfer(_account, _withdrawableFees);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x4189f90e0c0d061643abdea7d166a863801cfedb488a99b018ddc52ff9bdd3b0\",\"license\":\"MIT\"},\"contracts/turbo/NFLMarketFactoryV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"../libraries/IERC20Full.sol\\\";\\nimport \\\"../balancer/BPool.sol\\\";\\nimport \\\"./AbstractMarketFactoryV3.sol\\\";\\nimport \\\"./FeePot.sol\\\";\\nimport \\\"../libraries/SafeMathInt256.sol\\\";\\nimport \\\"../libraries/Sport.sol\\\";\\nimport \\\"../libraries/HasHeadToHeadMarket.sol\\\";\\nimport \\\"../libraries/HasSpreadMarket.sol\\\";\\nimport \\\"../libraries/HasOverUnderMarket.sol\\\";\\nimport \\\"../libraries/ResolveByScore.sol\\\";\\nimport \\\"../libraries/Versioned.sol\\\";\\n\\n// NFL is standard except ties are fine: they become NoContestOrDraw.\\n// As a consequence, half points are not added to the lines.\\ncontract NFLMarketFactoryV3 is\\n AbstractMarketFactoryV3,\\n SportView,\\n HasHeadToHeadMarket,\\n HasSpreadMarket,\\n HasOverUnderMarket,\\n ResolvesByScore,\\n Versioned\\n{\\n using SafeMathUint256 for uint256;\\n using SafeMathInt256 for int256;\\n\\n uint256 constant HeadToHead = 0;\\n uint256 constant Spread = 1;\\n uint256 constant OverUnder = 2;\\n\\n constructor(\\n address _owner,\\n IERC20Full _collateral,\\n uint256 _shareFactor,\\n FeePot _feePot,\\n uint256[3] memory _fees,\\n address _protocol,\\n address _linkNode\\n )\\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\\n Versioned(\\\"v1.2.0\\\")\\n ManagedByLink(_linkNode)\\n HasHeadToHeadMarket(HeadToHead, \\\"No Contest / Draw\\\")\\n HasSpreadMarket(Spread, \\\"No Contest\\\")\\n HasOverUnderMarket(OverUnder, \\\"No Contest\\\")\\n {}\\n\\n function createEvent(\\n uint256 _eventId,\\n string memory _homeTeamName,\\n uint256 _homeTeamId,\\n string memory _awayTeamName,\\n uint256 _awayTeamId,\\n uint256 _startTimestamp,\\n int256 _homeSpread,\\n int256 _totalScore,\\n int256[2] memory _moneylines // [home,away]\\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\\n makeSportsEvent(\\n _eventId,\\n _marketIds,\\n build3Lines(_homeSpread, _totalScore),\\n _startTimestamp,\\n _homeTeamId,\\n _awayTeamId,\\n _homeTeamName,\\n _awayTeamName\\n );\\n }\\n\\n function makeMarkets(\\n int256[2] memory _moneylines,\\n string memory _homeTeamName,\\n string memory _awayTeamName\\n ) internal returns (uint256[] memory _marketIds) {\\n _marketIds = new uint256[](3);\\n\\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\\n _marketIds[OverUnder] = makeOverUnderMarket();\\n }\\n\\n function resolveValidEvent(\\n SportsEvent memory _event,\\n uint256 _homeScore,\\n uint256 _awayScore\\n ) internal override {\\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\\n }\\n}\\n\",\"keccak256\":\"0x5dae4d4a6702a986262b57e2cb655e75b9c85b12945367505231e761d66d58b8\",\"license\":\"MIT\"},\"contracts/turbo/OwnedShareToken.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\nimport \\\"../libraries/Ownable.sol\\\";\\n\\ncontract OwnedERC20 is ERC20, Ownable {\\n constructor(\\n string memory name_,\\n string memory symbol_,\\n address _owner\\n ) ERC20(name_, symbol_) {\\n owner = _owner;\\n }\\n\\n function trustedTransfer(\\n address _from,\\n address _to,\\n uint256 _amount\\n ) external onlyOwner {\\n _transfer(_from, _to, _amount);\\n }\\n\\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\\n _mint(_target, _amount);\\n }\\n\\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\\n _burn(_target, _amount);\\n }\\n\\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\\n uint256 _balance = balanceOf(_target);\\n _burn(_target, _balance);\\n return _balance;\\n }\\n\\n function onTransferOwnership(address, address) internal override {}\\n}\\n\",\"keccak256\":\"0x1a60d8f5bb07018b446bf34cdc626ab309c5d2db2eaf75575622090af92c0086\",\"license\":\"MIT\"},\"contracts/turbo/TurboShareTokenFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.7.6;\\npragma abicoder v2;\\n\\nimport \\\"./OwnedShareToken.sol\\\";\\n\\nabstract contract TurboShareTokenFactory {\\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\\nabstract contract TurboShareTokenFactoryV1 {\\n function createShareTokens(\\n string[] memory _names,\\n string[] memory _symbols,\\n address _owner\\n ) internal returns (OwnedERC20[] memory) {\\n uint256 _numOutcomes = _names.length;\\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\\n\\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\\n }\\n return _tokens;\\n }\\n}\\n\",\"keccak256\":\"0x124906d94f6cae4049f50a2b71ddb9b8c0f0da8739b5c698166126bfe3173f8c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006007553480156200001657600080fd5b5060405162005c8138038062005c818339810160408190526200003991620005a0565b6040805180820182526006815265076312e322e360d41b60208083019190915282518084018452600a80825269139bc810dbdb9d195cdd60b21b8284018190528551808701875291825281840152845180860190955260118552704e6f20436f6e74657374202f204472617760781b92850192909252600080546001600160a01b03808e166001600160a01b03199283163317831617835560018054828f1690841617815560098d905560028054928d16929093169190911782559495879591949192908e8e8e8e8e8e8188602002015160035581600160200201516004558160026020020151600555600680546001600160a01b0319166001600160a01b038381169190911790915560405163095ea7b360e01b81529086169063095ea7b3906200016e90869060001990600401620006bc565b602060405180830381600087803b1580156200018957600080fd5b505af11580156200019e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001c4919062000693565b50600a620001d162000369565b81546001808201845560009384526020938490208351600b9093020180546001600160a01b0319166001600160a01b03909316929092178255828401518051939492936200022893928501929190910190620003df565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015160088201556101208201518051620002aa91600984019160209091019062000449565b506101409190910151600a909101805460ff1916911515919091179055505050600e85905550508151620002e79150600f90602084019062000487565b505050601082905580516200030490601190602084019062000487565b505050601282905580516200032190601390602084019062000487565b5050601480546001600160a01b0319166001600160a01b0393909316929092179091555080516200035a90601590602084019062000487565b505050505050505050620006ee565b6200037362000509565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b82805482825590600052602060002090810192821562000437579160200282015b828111156200043757825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000400565b506200044592915062000577565b5090565b82805482825590600052602060002090810192821562000437579160200282015b82811115620004375782518255916020019190600101906200046a565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620004bf576000855562000437565b82601f10620004da57805160ff191683800117855562000437565b82800160010185558215620004375791820182811115620004375782518255916020019190600101906200046a565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b5b8082111562000445576000815560010162000578565b80516200059b81620006d5565b919050565b6000806000806000806000610120888a031215620005bc578283fd5b8751620005c981620006d5565b80975050602080890151620005de81620006d5565b60408a015160608b01519198509650620005f881620006d5565b9450609f89018a1362000609578384fd5b604051606081016001600160401b03811182821017156200062657fe5b6040528060808b0160e08c018d8111156200063f578788fd5b875b6003811015620006605782518452928501929185019160010162000641565b508397506200066f816200058e565b965050505050506200068561010089016200058e565b905092959891949750929550565b600060208284031215620006a5578081fd5b81518015158114620006b5578182fd5b9392505050565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0381168114620006eb57600080fd5b50565b61558380620006fe6000396000f3fe60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212206d55cb956fa261b9e466a0b7a3739cd074a40423df7f3401dd50fb9214c085fe64736f6c63430007060033", + "deployedBytecode": "0x60806040523480156200001157600080fd5b5060043610620002805760003560e01c806397eef1871162000159578063d8dfeb4511620000c9578063ee750b191162000087578063ee750b191462000571578063f2fde38b1462000588578063f563c99a146200059f578063fbfcd55e14620005c6578063fedf6cb114620005dd5762000280565b8063d8dfeb451462000509578063e2c30b151462000513578063e5678dfa146200052a578063eb44fdd31462000541578063ec97908214620005675762000280565b8063cb68b0d81162000117578063cb68b0d8146200048d578063cc87adea14620004ba578063cdaac86214620004d1578063d4b6838e14620004e8578063d5da4f1d14620004f25762000280565b806397eef1871462000434578063992c9079146200044b578063a26956151462000462578063a544a62c1462000479578063b0e21e8a14620004835762000280565b80634c9f66c711620001f5578063787dce3d11620001b3578063787dce3d14620003e85780637d1d7fb814620003ff578063893d20e814620004095780638ce7442614620004135780638e0ed193146200041d5762000280565b80634c9f66c7146200036f57806353ac55f51462000388578063671eb69814620003ae57806371be2e4a14620003d45780637641ab0114620003de5762000280565b8063473a6d521162000243578063473a6d52146200031457806349a4d934146200032b5780634a7d036914620003425780634a875e0b146200034c5780634b2d9ffc14620003655762000280565b80630d8e6e2c1462000285578063221fff8114620002a757806332ecabe914620002c057806335a9cdad14620002d757806342e0ed1614620002fd575b600080fd5b6200028f620005f4565b6040516200029e919062003f83565b60405180910390f35b620002be620002b836600462003cf1565b6200068e565b005b620002be620002d136600462003998565b620009bb565b620002ee620002e836600462003cf1565b62000a09565b6040516200029e919062004135565b620002ee6200030e36600462003b2c565b62000e44565b620002ee6200032536600462003b2c565b62000e6b565b620002ee6200033c3660046200397b565b62000ea7565b620002ee62000eb9565b6200035662000f83565b6040516200029e919062003efe565b620002ee6200105a565b6200037962001060565b6040516200029e919062003ead565b6200039f6200039936600462003b2c565b6200106f565b6040516200029e919062003f13565b620003c5620003bf36600462003b2c565b620011f9565b6040516200029e9190620040fc565b620002ee6200146b565b620002ee62001471565b620002be620003f936600462003b2c565b62001477565b620002ee62001494565b620003796200149a565b62000379620014a9565b620002ee6200042e3660046200397b565b620014b8565b620002be6200044536600462003b2c565b62001574565b620002ee6200045c36600462003b5e565b62001591565b620002ee6200047336600462003b2c565b620019b3565b620002ee620019c5565b620002ee620019cb565b620004a46200049e36600462003b2c565b620019d1565b6040516200029e98979695949392919062003f1e565b620002ee620004cb36600462003b2c565b62001b37565b62000356620004e236600462003b2c565b62001b3e565b6200037962001be8565b620002be6200050336600462003b2c565b62001bf7565b6200037962001c14565b620002be620005243660046200397b565b62001c23565b620002ee6200053b366004620039d3565b62001c8f565b620005586200055236600462003b2c565b62001cdd565b6040516200029e91906200402b565b620002ee62001e7c565b620002be6200058236600462003b8c565b62001e82565b6200039f620005993660046200397b565b620023f6565b620005b6620005b036600462003b2c565b62002460565b6040516200029e92919062004111565b62000356620005d736600462003be0565b62002499565b620002ee620005ee36600462003b2c565b620024ed565b60158054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015620006845780601f10620006585761010080835404028352916020019162000684565b820191906000526020600020905b8154815290600101906020018083116200066657829003601f168201915b5050505050905090565b600a5483106200069d57600080fd5b600a8381548110620006ab57fe5b60009182526020909120600a600b90920201015460ff16620006cc57600080fd5b6000620006d98362000e6b565b6001546040516323b872dd60e01b81529192506001600160a01b0316906323b872dd90620007109033903090869060040162003ec1565b602060405180830381600087803b1580156200072b57600080fd5b505af115801562000740573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000766919062003a91565b506000600a85815481106200077757fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b03168352600181018054835181870281018701909452808452939491938583019392830182828015620007fb57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620007dc575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620008c057602002820191906000526020600020905b815481526020019060010190808311620008ab575b5050509183525050600a919091015460ff161515602090910152905060005b816020015151811015620009765781602001518181518110620008fe57fe5b60200260200101516001600160a01b031663c024cd2685876040518363ffffffff1660e01b81526004016200093592919062003ee5565b600060405180830381600087803b1580156200095057600080fd5b505af115801562000965573d6000803e3d6000fd5b505060019092019150620008df9050565b507fd81c0442e10068a9818f3aa093c9ccb804584690df572d7df3da2d892a6973f2858585604051620009ac93929190620042b2565b60405180910390a15050505050565b6000546001600160a01b03163314620009d357600080fd5b8015620009e657620009e462000eb9565b505b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b600a54600090841062000a1b57600080fd5b600a848154811062000a2957fe5b60009182526020909120600a600b90920201015460ff1662000a4a57600080fd5b6000600a858154811062000a5a57fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562000ade57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000abf575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562000ba357602002820191906000526020600020905b81548152602001906001019080831162000b8e575b5050509183525050600a919091015460ff161515602090910152905060005b81602001515181101562000c59578160200151818151811062000be157fe5b60200260200101516001600160a01b03166342986e1333876040518363ffffffff1660e01b815260040162000c1892919062003ee5565b600060405180830381600087803b15801562000c3357600080fd5b505af115801562000c48573d6000803e3d6000fd5b50506001909201915062000bc29050565b50600062000c678562000e6b565b9050600062000c98670de0b6b3a764000062000c918560a00151856200250f90919063ffffffff16565b906200253a565b9050600062000cc2670de0b6b3a764000062000c918660c00151866200250f90919063ffffffff16565b905062000cdc8162000cd5858562002550565b9062002550565b600780548401905560015460405163a9059cbb60e01b81529194506001600160a01b03169063a9059cbb9062000d19908990879060040162003ee5565b602060405180830381600087803b15801562000d3457600080fd5b505af115801562000d49573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d6f919062003a91565b50600254604051630ebdac0960e41b81526001600160a01b039091169063ebdac0909062000da290849060040162004135565b602060405180830381600087803b15801562000dbd57600080fd5b505af115801562000dd2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000df8919062003a91565b507fb6fdb729b2ed801daf629f0ab713e4a7a73619505790f6f27fd92d6f2c9688d788883360405162000e2e93929190620042b2565b60405180910390a15090925050505b9392505050565b6000818152600d602052604081205462000e5e81620011f9565b606001519150505b919050565b6000600954821015801562000e8a5750600954828162000e8757fe5b06155b62000e9457600080fd5b600954828162000ea057fe5b0492915050565b60086020526000908152604090205481565b6006546000906001600160a01b031633148062000ed557503330145b62000edf57600080fd5b600754801562000f7e57600060075560015460065460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb9262000f2692911690859060040162003ee5565b602060405180830381600087803b15801562000f4157600080fd5b505af115801562000f56573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000f7c919062003a91565b505b905090565b6060600062000f9162002566565b905060008167ffffffffffffffff8111801562000fad57600080fd5b5060405190808252806020026020018201604052801562000fd8578160200160208202803683370190505b5090506000805b600c5481101562001051578382111562000ff95762001051565b6000600c82815481106200100957fe5b906000526020600020015490506200102181620025b5565b156200104757808484815181106200103557fe5b60209081029190910101526001909201915b5060010162000fdf565b50909250505090565b60035481565b6002546001600160a01b031681565b600080600a83815481106200108057fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200110457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620010e5575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201805480602002602001604051908101604052809291908181526020018280548015620011c957602002820191906000526020600020905b815481526020019060010190808311620011b4575b5050509183525050600a919091015460ff161515602090910152604001516001600160a01b031615159392505050565b62001203620036fb565b6000828152600b602052604090819020815161014081019092528054829060ff1660048111156200123057fe5b60048111156200123c57fe5b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156200129157602002820191906000526020600020905b8154815260200190600101908083116200127c575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015620012eb57602002820191906000526020600020905b815481526020019060010190808311620012d6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620013af5780601f106200138357610100808354040283529160200191620013af565b820191906000526020600020905b8154815290600101906020018083116200139157829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620014475780601f106200141b5761010080835404028352916020019162001447565b820191906000526020600020905b8154815290600101906020018083116200142957829003601f168201915b50505050508152602001600882015481526020016009820154815250509050919050565b600c5490565b60095481565b6000546001600160a01b031633146200148f57600080fd5b600555565b60045481565b6000546001600160a01b031690565b6006546001600160a01b031681565b3360009081526008602052604081205480156200156e573360009081526008602052604080822091909155600154905163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9062001516908690859060040162003ee5565b602060405180830381600087803b1580156200153157600080fd5b505af115801562001546573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200156c919062003a91565b505b92915050565b6000546001600160a01b031633146200158c57600080fd5b600355565b60006200159e836200106f565b620015c65760405162461bcd60e51b8152600401620015bd9062004000565b60405180910390fd5b6000600a8481548110620015d657fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b031683526001810180548351818702810187019094528084529394919385830193928301828280156200165a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116200163b575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982018054806020026020016040519081016040528092919081815260200182805480156200171f57602002820191906000526020600020905b8154815260200190600101908083116200170a575b5050509183525050600a919091015460ff1615156020909101526040808201519051631c4a5de160e21b81529192506000916001600160a01b03909116906371297784906200177390339060040162003ead565b602060405180830381600087803b1580156200178e57600080fd5b505af1158015620017a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017c9919062003b45565b90506009546009548281620017da57fe5b040290506000620017eb8262000e6b565b9050600062001815670de0b6b3a764000062000c918660800151856200250f90919063ffffffff16565b905062001823828262002550565b84516001600160a01b0390811660009081526008602052604090819020805485019055600154905163a9059cbb60e01b8152929450169063a9059cbb9062001872908990869060040162003ee5565b602060405180830381600087803b1580156200188d57600080fd5b505af1158015620018a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620018c8919062003a91565b50600084606001519050600085604001516001600160a01b03166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200191257600080fd5b505afa15801562001927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262001951919081019062003ab0565b9050876001600160a01b03167f76ea0c89f1eef8b1ac3908910bbe5ee5120ff997f6b3bcc900659973e6a2ff128a886040015185858a898b6040516200199e97969594939291906200416d565b60405180910390a25091979650505050505050565b600d6020526000908152604090205481565b60075481565b60055481565b600b6020908152600091825260409182902080546003820154600483015460058401546006850180548851601f6002600019600185161561010002019093169290920491820189900489028101890190995280895260ff9095169793969295919491939290919083018282801562001a8d5780601f1062001a615761010080835404028352916020019162001a8d565b820191906000526020600020905b81548152906001019060200180831162001a6f57829003601f168201915b5050505060078301805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294959493509083018282801562001b215780601f1062001af55761010080835404028352916020019162001b21565b820191906000526020600020905b81548152906001019060200180831162001b0357829003601f168201915b5050505050908060080154908060090154905088565b6009540290565b6000818152600b602052604090206001018054606091908067ffffffffffffffff8111801562001b6d57600080fd5b5060405190808252806020026020018201604052801562001b98578160200160208202803683370190505b50925060005b8181101562001be05782818154811062001bb457fe5b906000526020600020015484828151811062001bcc57fe5b602090810291909101015260010162001b9e565b505050919050565b6014546001600160a01b031681565b6000546001600160a01b0316331462001c0f57600080fd5b600455565b6001546001600160a01b031681565b6000546001600160a01b0316331462001c3b57600080fd5b601480546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f6b7517523482c8d89ffbc530829d5decd506cf6dc60874b11fa26c8a53bb9fa99181900360200190a150565b600080805b845181101562001cd55762001cca62001cc286838151811062001cb357fe5b60200260200101518662001591565b839062002621565b915060010162001c94565b509392505050565b62001ce76200374f565b600a54821062001d035762001cfb62002634565b905062000e66565b600a828154811062001d1157fe5b60009182526020918290206040805161016081018252600b90930290910180546001600160a01b0316835260018101805483518187028101870190945280845293949193858301939283018282801562001d9557602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001d76575b505050505081526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820180548060200260200160405190810160405280929190818152602001828054801562001e5a57602002820191906000526020600020905b81548152602001906001019080831162001e45575b5050509183525050600a919091015460ff161515602090910152905062000e66565b600a5490565b6014546001600160a01b0316331462001e9a57600080fd5b6000868152600b602052604090206001815460ff16600481111562001ebb57fe5b1462001ec657600080fd5b600286600481111562001ed557fe5b60ff16101562001ee457600080fd5b60408051610140810190915281546200214a91908390829060ff16600481111562001f0b57fe5b600481111562001f1757fe5b81526020016001820180548060200260200160405190810160405280929190818152602001828054801562001f6c57602002820191906000526020600020905b81548152602001906001019080831162001f57575b505050505081526020016002820180548060200260200160405190810160405280929190818152602001828054801562001fc657602002820191906000526020600020905b81548152602001906001019080831162001fb1575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156200208a5780601f106200205e576101008083540402835291602001916200208a565b820191906000526020600020905b8154815290600101906020018083116200206c57829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152938201939291830182828015620021225780601f10620020f65761010080835404028352916020019162002122565b820191906000526020600020905b8154815290600101906020018083116200210457829003601f168201915b50505050508152602001600882015481526020016009820154815250508787876000620026aa565b1562002161576200215b8762002702565b620023c4565b6040805161014081019091528154620023c491908390829060ff1660048111156200218857fe5b60048111156200219457fe5b815260200160018201805480602002602001604051908101604052809291908181526020018280548015620021e957602002820191906000526020600020905b815481526020019060010190808311620021d4575b50505050508152602001600282018054806020026020016040519081016040528092919081815260200182805480156200224357602002820191906000526020600020905b8154815260200190600101908083116200222e575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015620023075780601f10620022db5761010080835404028352916020019162002307565b820191906000526020600020905b815481529060010190602001808311620022e957829003601f168201915b505050918352505060078201805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529382019392918301828280156200239f5780601f1062002373576101008083540402835291602001916200239f565b820191906000526020600020905b8154815290600101906020018083116200238157829003601f168201915b50505050508152602001600882015481526020016009820154815250508484620027b8565b80548690829060ff19166001836004811115620023dd57fe5b0217905550600881019290925560099091015550505050565b600080546001600160a01b031633146200240f57600080fd5b6001600160a01b0382166200242357600080fd5b6000546200243b906001600160a01b0316836200285e565b50600080546001600160a01b0383166001600160a01b03199091161790556001919050565b6200246a620036fb565b6000600c83815481106200247a57fe5b906000526020600020015490506200249281620011f9565b9150915091565b6014546060906001600160a01b03163314620024b457600080fd5b620024c1828a8962002862565b9050620024e08a82620024d58787620028fc565b888c8b8f8e6200296e565b9998505050505050505050565b600c8181548110620024fe57600080fd5b600091825260209091200154905081565b60008262002520575060006200156e565b828202828482816200252e57fe5b041462000e3d57600080fd5b6000808284816200254757fe5b04949350505050565b6000828211156200256057600080fd5b50900390565b600080805b600c5481101562000f7c576000600c82815481106200258657fe5b906000526020600020015490506200259e81620025b5565b15620025ab576001909201915b506001016200256b565b600080620025c38362001b3e565b90506000805b825181101562001cd5576000838281518110620025e257fe5b602002602001015190508060001415801562002606575062002604816200106f565b155b156200261757600192505062001cd5565b50600101620025c9565b60008282018381101562000e3d57600080fd5b6200263e6200374f565b50604080516000808252602082018181526101a083018452928201818152606083018390526080830182905260a0830182905260c0830182905260e083018290526101008301829052610120830182905261014083018290526101608301939093526101809091015290565b600060038214816002876004811115620026c057fe5b60808a015160a08b015192909114159250871415908614158380620026e25750825b80620026eb5750815b80620026f45750805b9a9950505050505050505050565b6000818152600b60209081526040808320600101805482518185028101850190935280835291929091908301828280156200275d57602002820191906000526020600020905b81548152602001906001019080831162002748575b5050505050905060005b8151811015620027b35760008282815181106200278057fe5b6020026020010151905080600014156200279b5750620027aa565b620027a881600062002b30565b505b60010162002767565b505050565b620027de8360200151600081518110620027ce57fe5b6020026020010151838362002c59565b6200281e8360200151600181518110620027f457fe5b602002602001015184604001516001815181106200280e57fe5b6020026020010151848462002c7b565b620027b383602001516002815181106200283457fe5b602002602001015184604001516002815181106200284e57fe5b6020026020010151848462002c9f565b5050565b604080516003808252608082019092526060916020820183803683370190505090506200289184848462002cae565b816000815181106200289f57fe5b602002602001018181525050620028b7838362002d76565b81600181518110620028c557fe5b602002602001018181525050620028db62002e1f565b81600281518110620028e957fe5b6020026020010181815250509392505050565b60408051600380825260808201909252606091602082018380368337019050509050620029298362002ee1565b816001815181106200293757fe5b6020026020010181815250506200294e8262002ee1565b816002815181106200295c57fe5b60200260200101818152505092915050565b6000888152600b602052604081205460ff1660048111156200298c57fe5b14620029ac5760405162461bcd60e51b8152600401620015bd9062003fda565b60005b8751811015620029ef5788600d60008a8481518110620029cb57fe5b602090810291909101810151825281019190915260400160002055600101620029af565b50600c805460018082019092557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7018990556000898152600b60209081526040909120805460ff191683178155895162002a519391909101918a0190620037bd565b506000888152600b60209081526040909120875162002a7992600290920191890190620037bd565b506000888152600b60209081526040909120600381018790556004810186905560058101859055835162002ab6926006909201918501906200380d565b506000888152600b60209081526040909120825162002ade926007909201918401906200380d565b507f42827ef26132f4417fc4fed922669edd09d6ee5bd5d9f369a5c97c0ff57bea47888888878787878c60405162002b1e98979695949392919062004232565b60405180910390a15050505050505050565b6000600a838154811062002b4057fe5b90600052602060002090600b02019050600081600101838154811062002b6257fe5b60009182526020822001546002840180546001600160a01b0319166001600160a01b039092169182179055600a8401805460ff1916905560038401859055426008850155604080516306fdde0360e01b8152905191935083916306fdde03916004808201928692909190829003018186803b15801562002be157600080fd5b505afa15801562002bf6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405262002c20919081019062003ab0565b90507f8008bbeee2e3c054e71d4965b4c22b41a2287cd6cc67c714bf918b538338be5f85838684604051620009ac94939291906200413e565b600062002c67838362002f3d565b905062002c75848262002b30565b50505050565b600062002c8a83838662002f6c565b905062002c98858262002b30565b5050505050565b600062002c8a83838662002fa4565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362002d6e939192909183018282801562002d425780601f1062002d165761010080835404028352916020019162002d42565b820191906000526020600020905b81548152906001019060200180831162002d2457829003601f168201915b5050505050848462002d688860016002811062002d5b57fe5b6020020151895162002fdd565b620030e7565b949350505050565b6011805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815260009362000e3d939192909183018282801562002e0a5780601f1062002dde5761010080835404028352916020019162002e0a565b820191906000526020600020905b81548152906001019060200180831162002dec57829003601f168201915b5050505050848462002d686001600262003112565b60138054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152600093849362002ebd9383018282801562002eb25780601f1062002e865761010080835404028352916020019162002eb2565b820191906000526020600020905b81548152906001019060200180831162002e9457829003601f168201915b505050505062003226565b905062002edb338262002ed36001600262003112565b6001620032e2565b91505090565b600080821215801562002ef55750600a8207155b1562002f0657506005810162000e66565b60008212801562002f235750600a826000038162002f2057fe5b07155b1562002f355750600419810162000e66565b508062000e66565b60008183111562002f51575060026200156e565b8183101562002f63575060016200156e565b5060006200156e565b60008382018381131562002f8557600291505062000e3d565b8381121562002f9957600191505062000e3d565b600091505062000e3d565b60008062002fb38585620034d6565b90508281131562002fc957600191505062000e3d565b8281121562002f9957600291505062000e3d565b6060600062002fec846200351f565b9050600062002ffb846200351f565b90508181016200301a8162000c916802a802f8630a240000866200250f565b9250620030368162000c916802a802f8630a240000856200250f565b9150670de0b6b3a76400008310156200304e57600080fd5b670de0b6b3a76400008210156200306457600080fd5b604080516003808252608082019092529060208201606080368337019050509350670de0b6b3a7640000846000815181106200309c57fe5b6020026020010181815250508284600181518110620030b757fe5b6020026020010181815250508184600281518110620030d257fe5b60200260200101818152505050505092915050565b600080620030f786868662003581565b9050620031083382856001620032e2565b9695505050505050565b60606000836200312457600062003127565b60015b60ff16830190508067ffffffffffffffff811180156200314657600080fd5b5060405190808252806020026020018201604052801562003171578160200160208202803683370190505b50915083156200319f57670de0b6b3a7640000826000815181106200319257fe5b6020026020010181815250505b60008385620031b8576802b5e3af16b1880000620031c3565b6802a802f8630a2400005b68ffffffffffffffffff1681620031d657fe5b049050600085620031e9576000620031ec565b60015b60ff1690505b828110156200321d57818482815181106200320957fe5b6020908102919091010152600101620031f2565b50505092915050565b60408051600380825260808201909252606091816020015b60608152602001906001900390816200323e57905050905081816000815181106200326557fe5b60200260200101819052506040518060400160405280600481526020016327bb32b960e11b815250816001815181106200329b57fe5b6020026020010181905250604051806040016040528060058152602001642ab73232b960d91b81525081600281518110620032d257fe5b6020026020010181905250919050565b600a80546040805161016081019091526001600160a01b03871681529091906020810162003311873062003606565b815260006020808301829052604083018290526004546060840152600554608084015260035460a08401524260c084015260e08301829052610100830188905286151561012090930192909252835460018082018655948252908290208351600b9092020180546001600160a01b0319166001600160a01b0390921691909117815582820151805193949193620033b1939285019291909101906200388f565b5060408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e082015160078201556101008201516008820155610120820151805162003433916009840191602090910190620037bd565b506101409190910151600a909101805460ff19169115159190911790556040517f037fdac9e4b37ad8b184ce958d7b275e578c9e03d4cfbc51aa75de25fdb6bbec906200348690839087908790620041bb565b60405180910390a1811562002d6e577fee570fee9d8debeedea533b8cdfde6b9d9995b915869d4d10d350e75a9bf0f8881604051620034c6919062004135565b60405180910390a1949350505050565b6000808312158015620034f25750826001600160ff1b03038213155b8062003510575060008312801562003510575082600160ff1b038212155b6200351a57600080fd5b500190565b6000808212156200355e576000829003620035556200354082606462002621565b62000c91836802a802f8630a2400006200250f565b91505062000e66565b62001cfb6200356f83606462002621565b690109a12906aff6100000906200253a565b60408051600380825260808201909252606091816020015b6060815260200190600190039081620035995790505090508381600081518110620035c057fe5b60200260200101819052508181600181518110620035da57fe5b60200260200101819052508281600281518110620035f457fe5b60200260200101819052509392505050565b815160609060008167ffffffffffffffff811180156200362557600080fd5b5060405190808252806020026020018201604052801562003650578160200160208202803683370190505b50905060005b82811015620036f2578581815181106200366c57fe5b60200260200101518682815181106200368157fe5b6020026020010151866040516200369890620038e7565b620036a69392919062003f98565b604051809103906000f080158015620036c3573d6000803e3d6000fd5b50828281518110620036d157fe5b6001600160a01b039092166020928302919091019091015260010162003656565b50949350505050565b60408051610140810190915280600081526020016060815260200160608152602001600081526020016000815260200160008152602001606081526020016060815260200160008152602001600081525090565b60405180610160016040528060006001600160a01b031681526020016060815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001606081526020016000151581525090565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb578251825591602001919060010190620037de565b5062003809929150620038f5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620038455760008555620037fb565b82601f106200386057805160ff1916838001178555620037fb565b82800160010185558215620037fb5791820182811115620037fb578251825591602001919060010190620037de565b828054828255906000526020600020908101928215620037fb579160200282015b82811115620037fb57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620038b0565b6111f3806200435b83390190565b5b80821115620038095760008155600101620038f6565b80356001600160a01b038116811462000e6657600080fd5b600082601f83011262003935578081fd5b81356200394c6200394682620042f6565b620042d1565b81815284602083860101111562003961578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156200398d578081fd5b62000e3d826200390c565b60008060408385031215620039ab578081fd5b620039b6836200390c565b91506020830135620039c88162004348565b809150509250929050565b60008060408385031215620039e6578182fd5b823567ffffffffffffffff80821115620039fe578384fd5b818501915085601f83011262003a12578384fd5b813560208282111562003a2157fe5b808202925062003a33818401620042d1565b8281528181019085830185870184018b101562003a4e578889fd5b8896505b8487101562003a7257803583526001969096019591830191830162003a52565b50965062003a8490508782016200390c565b9450505050509250929050565b60006020828403121562003aa3578081fd5b815162000e3d8162004348565b60006020828403121562003ac2578081fd5b815167ffffffffffffffff81111562003ad9578182fd5b8201601f8101841362003aea578182fd5b805162003afb6200394682620042f6565b81815285602083850101111562003b10578384fd5b62003b2382602083016020860162004319565b95945050505050565b60006020828403121562003b3e578081fd5b5035919050565b60006020828403121562003b57578081fd5b5051919050565b6000806040838503121562003b71578182fd5b8235915062003b83602084016200390c565b90509250929050565b60008060008060008060c0878903121562003ba5578182fd5b8635955060208701356005811062003bbb578283fd5b95989597505050506040840135936060810135936080820135935060a0909101359150565b6000806000806000806000806000610140808b8d03121562003c00578788fd5b8a35995060208b013567ffffffffffffffff8082111562003c1f57898afd5b62003c2d8e838f0162003924565b9a5060408d0135995060608d013591508082111562003c4a578586fd5b62003c588e838f0162003924565b985060808d0135975060a08d0135965060c08d0135955060e08d013594508d61011f8e011262003c86578384fd5b604051915060408201828110828211171562003c9e57fe5b60405250806101008d01838e018f101562003cb7578485fd5b8493505b600284101562003cdd5780358252600193909301926020918201910162003cbb565b505080925050509295985092959850929598565b60008060006060848603121562003d06578081fd5b833592506020840135915062003d1f604085016200390c565b90509250925092565b6001600160a01b03169052565b6000815180845260208085019450808401835b8381101562003d6f5781516001600160a01b03168752958201959082019060010162003d48565b509495945050505050565b6000815180845260208085019450808401835b8381101562003d6f5781518752958201959082019060010162003d8d565b15159052565b6005811062003dbc57fe5b9052565b6000815180845262003dda81602086016020860162004319565b601f01601f19169290920160200192915050565b600061014062003e0084845162003db1565b602083015181602086015262003e198286018262003d7a565b9150506040830151848203604086015262003e35828262003d7a565b915050606083015160608501526080830151608085015260a083015160a085015260c083015184820360c086015262003e6f828262003dc0565b91505060e083015184820360e086015262003e8b828262003dc0565b6101008581015190870152610120948501519490950193909352509192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b60006020825262000e3d602083018462003d7a565b901515815260200190565b600061010062003f2f838c62003db1565b89602084015288604084015287606084015280608084015262003f558184018862003dc0565b905082810360a084015262003f6b818762003dc0565b60c0840195909552505060e001529695505050505050565b60006020825262000e3d602083018462003dc0565b60006060825262003fad606083018662003dc0565b828103602084015262003fc1818662003dc0565b91505060018060a01b0383166040830152949350505050565b6020808252600c908201526b6576656e742065786973747360a01b604082015260600190565b6020808252601190820152701b585c9ad95d081d5b9c995cdbdb1d9959607a1b604082015260600190565b6000602082526200404160208301845162003d28565b60208301516101608060408501526200405f61018085018362003d35565b9150604085015162004075606086018262003d28565b5060608501516080850152608085015160a085015260a085015160c085015260c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140601f198685030181870152620040db848362003d7a565b935080870151915050620040f28286018262003dab565b5090949350505050565b60006020825262000e3d602083018462003dee565b60006040825262004126604083018562003dee565b90508260208301529392505050565b90815260200190565b600085825260018060a01b03851660208301528360408301526080606083015262003108608083018462003dc0565b600088825260018060a01b038816602083015286604083015260e060608301526200419c60e083018762003dc0565b60808301959095525060a081019290925260c090910152949350505050565b600060608201858352602060608185015281865180845260808601915060808382028701019350828801855b828110156200421957607f198887030184526200420686835162003dc0565b95509284019290840190600101620041e7565b5050505050828103604084015262003108818562003d7a565b60006101008a83528060208401526200424e8184018b62003d7a565b9050828103604084015262004264818a62003d7a565b905087606084015286608084015282810360a084015262004286818762003dc0565b905082810360c08401526200429c818662003dc0565b9150508260e08301529998505050505050505050565b92835260208301919091526001600160a01b0316604082015260600190565b60405181810167ffffffffffffffff81118282101715620042ee57fe5b604052919050565b600067ffffffffffffffff8211156200430b57fe5b50601f01601f191660200190565b60005b83811015620043365781810151838201526020016200431c565b8381111562002c755750506000910152565b80151581146200435757600080fd5b5056fe60806040523480156200001157600080fd5b50604051620011f3380380620011f3833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b5060405260209081015185519093508592508491620001bd9160039185019062000219565b508051620001d390600490602084019062000219565b5050600580546001600160a01b039390931661010090810233909102610100600160a81b031960ff199095166012178516179093169290921790915550620002c5915050565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200025157600085556200029c565b82601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b5b80821115620002aa5760008155600101620002af565b610f1e80620002d56000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a2578063a457c2d711610071578063a457c2d714610343578063a9059cbb1461036f578063c024cd261461039b578063dd62ed3e146103c7578063f2fde38b146103f55761010b565b806370a08231146102cb57806371297784146102f1578063893d20e81461031757806395d89b411461033b5761010b565b806323b872dd116100de57806323b872dd1461021f578063313ce56714610255578063395093511461027357806342986e131461029f5761010b565b806306fdde0314610110578063095ea7b31461018d5780630fb66557146101cd57806318160ddd14610205575b600080fd5b61011861041b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015257818101518382015260200161013a565b50505050905090810190601f16801561017f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101b9600480360360408110156101a357600080fd5b506001600160a01b0381351690602001356104b1565b604080519115158252519081900360200190f35b610203600480360360608110156101e357600080fd5b506001600160a01b038135811691602081013590911690604001356104ce565b005b61020d6104fa565b60408051918252519081900360200190f35b6101b96004803603606081101561023557600080fd5b506001600160a01b03813581169160208101359091169060400135610500565b61025d610587565b6040805160ff9092168252519081900360200190f35b6101b96004803603604081101561028957600080fd5b506001600160a01b038135169060200135610590565b610203600480360360408110156102b557600080fd5b506001600160a01b0381351690602001356105de565b61020d600480360360208110156102e157600080fd5b50356001600160a01b0316610608565b61020d6004803603602081101561030757600080fd5b50356001600160a01b0316610623565b61031f61065f565b604080516001600160a01b039092168252519081900360200190f35b610118610673565b6101b96004803603604081101561035957600080fd5b506001600160a01b0381351690602001356106d4565b6101b96004803603604081101561038557600080fd5b506001600160a01b03813516906020013561073c565b610203600480360360408110156103b157600080fd5b506001600160a01b038135169060200135610750565b61020d600480360360408110156103dd57600080fd5b506001600160a01b0381358116916020013516610776565b6101b96004803603602081101561040b57600080fd5b50356001600160a01b03166107a1565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b820191906000526020600020905b81548152906001019060200180831161048a57829003601f168201915b5050505050905090565b60006104c56104be610818565b848461081c565b50600192915050565b60055461010090046001600160a01b031633146104ea57600080fd5b6104f5838383610908565b505050565b60025490565b600061050d848484610908565b61057d84610519610818565b61057885604051806060016040528060288152602001610e32602891396001600160a01b038a16600090815260016020526040812090610557610818565b6001600160a01b031681526020810191909152604001600020549190610a63565b61081c565b5060019392505050565b60055460ff1690565b60006104c561059d610818565b8461057885600160006105ae610818565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610afa565b60055461010090046001600160a01b031633146105fa57600080fd5b6106048282610b5b565b5050565b6001600160a01b031660009081526020819052604090205490565b60055460009061010090046001600160a01b0316331461064257600080fd5b600061064d83610608565b90506106598382610b5b565b92915050565b60055461010090046001600160a01b031690565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104a75780601f1061047c576101008083540402835291602001916104a7565b60006104c56106e1610818565b8461057885604051806060016040528060258152602001610ec4602591396001600061070b610818565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610a63565b60006104c5610749610818565b8484610908565b60055461010090046001600160a01b0316331461076c57600080fd5b6106048282610c57565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60055460009061010090046001600160a01b031633146107c057600080fd5b6001600160a01b0382166107d357600080fd5b6005546107ee9061010090046001600160a01b031683610604565b50600580546001600160a01b03831661010002610100600160a81b03199091161790556001919050565b3390565b6001600160a01b0383166108615760405162461bcd60e51b8152600401808060200182810382526024815260200180610ea06024913960400191505060405180910390fd5b6001600160a01b0382166108a65760405162461bcd60e51b8152600401808060200182810382526022815260200180610dea6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661094d5760405162461bcd60e51b8152600401808060200182810382526025815260200180610e7b6025913960400191505060405180910390fd5b6001600160a01b0382166109925760405162461bcd60e51b8152600401808060200182810382526023815260200180610da56023913960400191505060405180910390fd5b61099d8383836104f5565b6109da81604051806060016040528060268152602001610e0c602691396001600160a01b0386166000908152602081905260409020549190610a63565b6001600160a01b038085166000908152602081905260408082209390935590841681522054610a099082610afa565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610af25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610ab7578181015183820152602001610a9f565b50505050905090810190601f168015610ae45780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610b54576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ba05760405162461bcd60e51b8152600401808060200182810382526021815260200180610e5a6021913960400191505060405180910390fd5b610bac826000836104f5565b610be981604051806060016040528060228152602001610dc8602291396001600160a01b0385166000908152602081905260409020549190610a63565b6001600160a01b038316600090815260208190526040902055600254610c0f9082610d47565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216610cb2576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610cbe600083836104f5565b600254610ccb9082610afa565b6002556001600160a01b038216600090815260208190526040902054610cf19082610afa565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600082821115610d9e576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c881513fca5a75d47e02fc1c04920461b43ce001b23b37bd2a0244cb5b4737ce64736f6c63430007060033a26469706673582212206d55cb956fa261b9e466a0b7a3739cd074a40423df7f3401dd50fb9214c085fe64736f6c63430007060033", "devdoc": { "kind": "dev", "methods": { @@ -1479,8 +1479,8 @@ "label": "address", "numberOfBytes": "20" }, - "t_array(t_contract(OwnedERC20)25830)dyn_storage": { - "base": "t_contract(OwnedERC20)25830", + "t_array(t_contract(OwnedERC20)25781)dyn_storage": { + "base": "t_contract(OwnedERC20)25781", "encoding": "dynamic_array", "label": "contract OwnedERC20[]", "numberOfBytes": "32" @@ -1518,7 +1518,7 @@ "label": "contract IERC20Full", "numberOfBytes": "20" }, - "t_contract(OwnedERC20)25830": { + "t_contract(OwnedERC20)25781": { "encoding": "inplace", "label": "contract OwnedERC20", "numberOfBytes": "20" @@ -1577,7 +1577,7 @@ "label": "shareTokens", "offset": 0, "slot": "1", - "type": "t_array(t_contract(OwnedERC20)25830)dyn_storage" + "type": "t_array(t_contract(OwnedERC20)25781)dyn_storage" }, { "astId": 15185, @@ -1585,7 +1585,7 @@ "label": "winner", "offset": 0, "slot": "2", - "type": "t_contract(OwnedERC20)25830" + "type": "t_contract(OwnedERC20)25781" }, { "astId": 15187, diff --git a/packages/smart/deployments/maticMumbai/solcInputs/8300c5e3118901fdc5a46905f80222b0.json b/packages/smart/deployments/maticMumbai/solcInputs/8300c5e3118901fdc5a46905f80222b0.json new file mode 100644 index 000000000..82cfc699b --- /dev/null +++ b/packages/smart/deployments/maticMumbai/solcInputs/8300c5e3118901fdc5a46905f80222b0.json @@ -0,0 +1,223 @@ +{ + "language": "Solidity", + "sources": { + "contracts/balancer/BColor.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\ninterface BColor {\n function getColor() external view returns (bytes32);\n}\n\ncontract BBronze is BColor {\n function getColor() external pure override returns (bytes32) {\n return bytes32(\"BRONZE\");\n }\n}\n" + }, + "contracts/balancer/BConst.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BColor.sol\";\n\ncontract BConst is BBronze {\n uint256 public constant BONE = 10**18;\n\n uint256 public constant MIN_BOUND_TOKENS = 2;\n uint256 public constant MAX_BOUND_TOKENS = 8;\n\n uint256 public constant MIN_FEE = BONE / 10**6;\n uint256 public constant MAX_FEE = BONE / 10;\n uint256 public constant EXIT_FEE = 0;\n\n uint256 public constant MIN_WEIGHT = BONE;\n uint256 public constant MAX_WEIGHT = BONE * 50;\n uint256 public constant MAX_TOTAL_WEIGHT = BONE * 50;\n uint256 public constant MIN_BALANCE = BONE / 10**12;\n\n uint256 public constant INIT_POOL_SUPPLY = BONE * 100;\n\n uint256 public constant MIN_BPOW_BASE = 1 wei;\n uint256 public constant MAX_BPOW_BASE = (2 * BONE) - 1 wei;\n uint256 public constant BPOW_PRECISION = BONE / 10**10;\n\n uint256 public constant MAX_IN_RATIO = BONE / 2;\n uint256 public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei;\n}\n" + }, + "contracts/balancer/BNum.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BConst.sol\";\n\ncontract BNum is BConst {\n function btoi(uint256 a) internal pure returns (uint256) {\n return a / BONE;\n }\n\n function bfloor(uint256 a) internal pure returns (uint256) {\n return btoi(a) * BONE;\n }\n\n function badd(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"ERR_ADD_OVERFLOW\");\n return c;\n }\n\n function bsub(uint256 a, uint256 b) internal pure returns (uint256) {\n (uint256 c, bool flag) = bsubSign(a, b);\n require(!flag, \"ERR_SUB_UNDERFLOW\");\n return c;\n }\n\n function bsubSign(uint256 a, uint256 b) internal pure returns (uint256, bool) {\n if (a >= b) {\n return (a - b, false);\n } else {\n return (b - a, true);\n }\n }\n\n function bmul(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c0 = a * b;\n require(a == 0 || c0 / a == b, \"ERR_MUL_OVERFLOW\");\n uint256 c1 = c0 + (BONE / 2);\n require(c1 >= c0, \"ERR_MUL_OVERFLOW\");\n uint256 c2 = c1 / BONE;\n return c2;\n }\n\n function bdiv(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b != 0, \"ERR_DIV_ZERO\");\n uint256 c0 = a * BONE;\n require(a == 0 || c0 / a == BONE, \"ERR_DIV_INTERNAL\"); // bmul overflow\n uint256 c1 = c0 + (b / 2);\n require(c1 >= c0, \"ERR_DIV_INTERNAL\"); // badd require\n uint256 c2 = c1 / b;\n return c2;\n }\n\n // DSMath.wpow\n function bpowi(uint256 a, uint256 n) internal pure returns (uint256) {\n uint256 z = n % 2 != 0 ? a : BONE;\n\n for (n /= 2; n != 0; n /= 2) {\n a = bmul(a, a);\n\n if (n % 2 != 0) {\n z = bmul(z, a);\n }\n }\n return z;\n }\n\n // Compute b^(e.w) by splitting it into (b^e)*(b^0.w).\n // Use `bpowi` for `b^e` and `bpowK` for k iterations\n // of approximation of b^0.w\n function bpow(uint256 base, uint256 exp) internal pure returns (uint256) {\n require(base >= MIN_BPOW_BASE, \"ERR_BPOW_BASE_TOO_LOW\");\n require(base <= MAX_BPOW_BASE, \"ERR_BPOW_BASE_TOO_HIGH\");\n\n uint256 whole = bfloor(exp);\n uint256 remain = bsub(exp, whole);\n\n uint256 wholePow = bpowi(base, btoi(whole));\n\n if (remain == 0) {\n return wholePow;\n }\n\n uint256 partialResult = bpowApprox(base, remain, BPOW_PRECISION);\n return bmul(wholePow, partialResult);\n }\n\n function bpowApprox(\n uint256 base,\n uint256 exp,\n uint256 precision\n ) internal pure returns (uint256) {\n // term 0:\n uint256 a = exp;\n (uint256 x, bool xneg) = bsubSign(base, BONE);\n uint256 term = BONE;\n uint256 sum = term;\n bool negative = false;\n\n // term(k) = numer / denom\n // = (product(a - i - 1, i=1-->k) * x^k) / (k!)\n // each iteration, multiply previous term by (a-(k-1)) * x / k\n // continue until term is less than precision\n for (uint256 i = 1; term >= precision; i++) {\n uint256 bigK = i * BONE;\n (uint256 c, bool cneg) = bsubSign(a, bsub(bigK, BONE));\n term = bmul(term, bmul(c, x));\n term = bdiv(term, bigK);\n if (term == 0) break;\n\n if (xneg) negative = !negative;\n if (cneg) negative = !negative;\n if (negative) {\n sum = bsub(sum, term);\n } else {\n sum = badd(sum, term);\n }\n }\n\n return sum;\n }\n}\n" + }, + "contracts/turbo/AMMFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma experimental ABIEncoderV2;\n\nimport \"../balancer/BFactory.sol\";\nimport \"../libraries/SafeMathUint256.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"../balancer/BNum.sol\";\n\ncontract AMMFactory is BNum {\n using SafeMathUint256 for uint256;\n\n uint256 private constant MAX_UINT = 2**256 - 1;\n uint256 private constant MIN_INITIAL_LIQUIDITY = BONE * 100;\n\n BFactory public bFactory;\n // MarketFactory => Market => BPool\n mapping(address => mapping(uint256 => BPool)) public pools;\n uint256 fee;\n\n event PoolCreated(\n address pool,\n address indexed marketFactory,\n uint256 indexed marketId,\n address indexed creator,\n address lpTokenRecipient\n );\n event LiquidityChanged(\n address indexed marketFactory,\n uint256 indexed marketId,\n address indexed user,\n address recipient,\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\n int256 collateral,\n int256 lpTokens,\n uint256[] sharesReturned\n );\n event SharesSwapped(\n address indexed marketFactory,\n uint256 indexed marketId,\n address indexed user,\n uint256 outcome,\n // from the perspective of the user. e.g. collateral is negative when buying\n int256 collateral,\n int256 shares,\n uint256 price\n );\n\n constructor(BFactory _bFactory, uint256 _fee) {\n bFactory = _bFactory;\n fee = _fee;\n }\n\n function createPool(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _initialLiquidity,\n address _lpTokenRecipient\n ) public returns (uint256) {\n require(pools[address(_marketFactory)][_marketId] == BPool(0), \"Pool already created\");\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n uint256 _sets = _marketFactory.calcShares(_initialLiquidity);\n\n // Comparing to sets because sets are normalized to 10e18.\n require(_sets >= MIN_INITIAL_LIQUIDITY, \"Initial liquidity must be at least 100 collateral.\");\n\n // Turn collateral into shares\n IERC20Full _collateral = _marketFactory.collateral();\n require(\n _collateral.allowance(msg.sender, address(this)) >= _initialLiquidity,\n \"insufficient collateral allowance for initial liquidity\"\n );\n\n _collateral.transferFrom(msg.sender, address(this), _initialLiquidity);\n _collateral.approve(address(_marketFactory), MAX_UINT);\n\n _marketFactory.mintShares(_marketId, _sets, address(this));\n\n // Create pool\n BPool _pool = bFactory.newBPool();\n\n // Add each outcome to the pool. Collateral is NOT added.\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n OwnedERC20 _token = _market.shareTokens[i];\n _token.approve(address(_pool), MAX_UINT);\n _pool.bind(address(_token), _sets, _market.initialOdds[i]);\n }\n\n // Set the swap fee.\n _pool.setSwapFee(fee);\n\n // Finalize pool setup\n _pool.finalize();\n\n pools[address(_marketFactory)][_marketId] = _pool;\n\n // Pass along LP tokens for initial liquidity\n uint256 _lpTokenBalance = _pool.balanceOf(address(this)) - (BONE / 1000);\n\n // Burn (BONE / 1000) lp tokens to prevent the bpool from locking up. When all liquidity is removed.\n _pool.transfer(address(0x0), (BONE / 1000));\n _pool.transfer(_lpTokenRecipient, _lpTokenBalance);\n\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n _balances[i] = 0;\n }\n\n emit PoolCreated(address(_pool), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\n emit LiquidityChanged(\n address(_marketFactory),\n _marketId,\n msg.sender,\n _lpTokenRecipient,\n -int256(_initialLiquidity),\n int256(_lpTokenBalance),\n _balances\n );\n\n return _lpTokenBalance;\n }\n\n function addLiquidity(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _collateralIn,\n uint256 _minLPTokensOut,\n address _lpTokenRecipient\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n require(_pool != BPool(0), \"Pool needs to be created\");\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n // Turn collateral into shares\n IERC20Full _collateral = _marketFactory.collateral();\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\n _collateral.approve(address(_marketFactory), MAX_UINT);\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\n _marketFactory.mintShares(_marketId, _sets, address(this));\n\n // Find poolAmountOut\n _poolAmountOut = MAX_UINT;\n\n {\n uint256 _totalSupply = _pool.totalSupply();\n uint256[] memory _maxAmountsIn = new uint256[](_market.shareTokens.length);\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n _maxAmountsIn[i] = _sets;\n\n OwnedERC20 _token = _market.shareTokens[i];\n uint256 _bPoolTokenBalance = _pool.getBalance(address(_token));\n\n // This is the result the following when solving for poolAmountOut:\n // uint256 ratio = bdiv(poolAmountOut, poolTotal);\n // uint256 tokenAmountIn = bmul(ratio, bal);\n uint256 _tokenPoolAmountOut =\n (((((_sets * BONE) - (BONE / 2)) * _totalSupply) / _bPoolTokenBalance) - (_totalSupply / 2)) / BONE;\n\n if (_tokenPoolAmountOut < _poolAmountOut) {\n _poolAmountOut = _tokenPoolAmountOut;\n }\n }\n _pool.joinPool(_poolAmountOut, _maxAmountsIn);\n }\n\n require(_poolAmountOut >= _minLPTokensOut, \"Would not have received enough LP tokens\");\n\n _pool.transfer(_lpTokenRecipient, _poolAmountOut);\n\n // Transfer the remaining shares back to _lpTokenRecipient.\n _balances = new uint256[](_market.shareTokens.length);\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n OwnedERC20 _token = _market.shareTokens[i];\n _balances[i] = _token.balanceOf(address(this));\n if (_balances[i] > 0) {\n _token.transfer(_lpTokenRecipient, _balances[i]);\n }\n }\n\n emit LiquidityChanged(\n address(_marketFactory),\n _marketId,\n msg.sender,\n _lpTokenRecipient,\n -int256(_collateralIn),\n int256(_poolAmountOut),\n _balances\n );\n }\n\n function removeLiquidity(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _lpTokensIn,\n uint256 _minCollateralOut,\n address _collateralRecipient\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n require(_pool != BPool(0), \"Pool needs to be created\");\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n _pool.transferFrom(msg.sender, address(this), _lpTokensIn);\n\n uint256[] memory exitPoolEstimate;\n {\n uint256[] memory minAmountsOut = new uint256[](_market.shareTokens.length);\n exitPoolEstimate = _pool.calcExitPool(_lpTokensIn, minAmountsOut);\n _pool.exitPool(_lpTokensIn, minAmountsOut);\n }\n\n // Find the number of sets to sell.\n uint256 _setsToSell = MAX_UINT;\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n uint256 _acquiredTokenBalance = exitPoolEstimate[i];\n if (_acquiredTokenBalance < _setsToSell) _setsToSell = _acquiredTokenBalance;\n }\n\n // Must be a multiple of share factor.\n _setsToSell = (_setsToSell / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\n\n bool _resolved = _marketFactory.isMarketResolved(_marketId);\n if (_resolved) {\n _collateralOut = _marketFactory.claimWinnings(_marketId, _collateralRecipient);\n } else {\n _collateralOut = _marketFactory.burnShares(_marketId, _setsToSell, _collateralRecipient);\n }\n require(_collateralOut > _minCollateralOut, \"Amount of collateral returned too low.\");\n\n // Transfer the remaining shares back to _collateralRecipient.\n _balances = new uint256[](_market.shareTokens.length);\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n OwnedERC20 _token = _market.shareTokens[i];\n if (_resolved && _token == _market.winner) continue; // all winning shares claimed when market is resolved\n _balances[i] = exitPoolEstimate[i] - _setsToSell;\n if (_balances[i] > 0) {\n _token.transfer(_collateralRecipient, _balances[i]);\n }\n }\n\n emit LiquidityChanged(\n address(_marketFactory),\n _marketId,\n msg.sender,\n _collateralRecipient,\n int256(_collateralOut),\n -int256(_lpTokensIn),\n _balances\n );\n }\n\n function buy(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _outcome,\n uint256 _collateralIn,\n uint256 _minTokensOut\n ) external returns (uint256) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n require(_pool != BPool(0), \"Pool needs to be created\");\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n IERC20Full _collateral = _marketFactory.collateral();\n _collateral.transferFrom(msg.sender, address(this), _collateralIn);\n uint256 _sets = _marketFactory.calcShares(_collateralIn);\n _marketFactory.mintShares(_marketId, _sets, address(this));\n\n uint256 _totalDesiredOutcome = _sets;\n {\n OwnedERC20 _desiredToken = _market.shareTokens[_outcome];\n\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n if (i == _outcome) continue;\n OwnedERC20 _token = _market.shareTokens[i];\n (uint256 _acquiredToken, ) =\n _pool.swapExactAmountIn(address(_token), _sets, address(_desiredToken), 0, MAX_UINT);\n _totalDesiredOutcome += _acquiredToken;\n }\n require(_totalDesiredOutcome >= _minTokensOut, \"Slippage exceeded\");\n\n _desiredToken.transfer(msg.sender, _totalDesiredOutcome);\n }\n\n emit SharesSwapped(\n address(_marketFactory),\n _marketId,\n msg.sender,\n _outcome,\n -int256(_collateralIn),\n int256(_totalDesiredOutcome),\n bdiv(_sets, _totalDesiredOutcome)\n );\n\n return _totalDesiredOutcome;\n }\n\n function sellForCollateral(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _outcome,\n uint256[] memory _shareTokensIn,\n uint256 _minSetsOut\n ) external returns (uint256) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n require(_pool != BPool(0), \"Pool needs to be created\");\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n uint256 _setsOut = MAX_UINT;\n uint256 _totalUndesiredTokensIn = 0;\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n _totalUndesiredTokensIn += _shareTokensIn[i];\n }\n\n {\n _market.shareTokens[_outcome].transferFrom(msg.sender, address(this), _totalUndesiredTokensIn);\n _market.shareTokens[_outcome].approve(address(_pool), MAX_UINT);\n\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n if (i == _outcome) continue;\n OwnedERC20 _token = _market.shareTokens[i];\n (uint256 tokenAmountOut, ) =\n _pool.swapExactAmountIn(\n address(_market.shareTokens[_outcome]),\n _shareTokensIn[i],\n address(_token),\n 0,\n MAX_UINT\n );\n\n //Ensure tokenAmountOut is a multiple of shareFactor.\n tokenAmountOut = (tokenAmountOut / _marketFactory.shareFactor()) * _marketFactory.shareFactor();\n if (tokenAmountOut < _setsOut) _setsOut = tokenAmountOut;\n }\n\n require(_setsOut >= _minSetsOut, \"Minimum sets not available.\");\n _marketFactory.burnShares(_marketId, _setsOut, msg.sender);\n }\n\n // Transfer undesired token balance back.\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n OwnedERC20 _token = _market.shareTokens[i];\n uint256 _balance = _token.balanceOf(address(this));\n if (_balance > 0) {\n _token.transfer(msg.sender, _balance);\n }\n }\n\n uint256 _collateralOut = _marketFactory.calcCost(_setsOut);\n emit SharesSwapped(\n address(_marketFactory),\n _marketId,\n msg.sender,\n _outcome,\n int256(_collateralOut),\n -int256(_totalUndesiredTokensIn),\n bdiv(_setsOut, _totalUndesiredTokensIn)\n );\n\n return _collateralOut;\n }\n\n // Returns an array of token values for the outcomes of the market, relative to the first outcome.\n // So the first outcome is 10**18 and all others are higher or lower.\n // Prices can be derived due to the fact that the total of all outcome shares equals one collateral, possibly with a scaling factor,\n function tokenRatios(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\n external\n view\n returns (uint256[] memory)\n {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n // Pool does not exist. Do not want to revert because multicall.\n if (_pool == BPool(0)) {\n return new uint256[](0);\n }\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n address _basisToken = address(_market.shareTokens[0]);\n uint256[] memory _ratios = new uint256[](_market.shareTokens.length);\n _ratios[0] = 10**18;\n for (uint256 i = 1; i < _market.shareTokens.length; i++) {\n uint256 _price = _pool.getSpotPrice(_basisToken, address(_market.shareTokens[i]));\n _ratios[i] = _price;\n }\n return _ratios;\n }\n\n function getPoolBalances(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\n external\n view\n returns (uint256[] memory)\n {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n // Pool does not exist. Do not want to revert because multicall.\n if (_pool == BPool(0)) {\n return new uint256[](0);\n }\n\n address[] memory _tokens = _pool.getCurrentTokens();\n uint256[] memory _balances = new uint256[](_tokens.length);\n for (uint256 i = 0; i < _tokens.length; i++) {\n _balances[i] = _pool.getBalance(_tokens[i]);\n }\n return _balances;\n }\n\n function getPoolWeights(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\n external\n view\n returns (uint256[] memory)\n {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n // Pool does not exist. Do not want to revert because multicall.\n if (_pool == BPool(0)) {\n return new uint256[](0);\n }\n\n address[] memory _tokens = _pool.getCurrentTokens();\n uint256[] memory _weights = new uint256[](_tokens.length);\n for (uint256 i = 0; i < _tokens.length; i++) {\n _weights[i] = _pool.getDenormalizedWeight(_tokens[i]);\n }\n return _weights;\n }\n\n function getSwapFee(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (uint256) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n return _pool.getSwapFee();\n }\n\n function getPoolTokenBalance(\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n address _user\n ) external view returns (uint256) {\n BPool _pool = pools[address(_marketFactory)][_marketId];\n return _pool.balanceOf(_user);\n }\n\n function getPool(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId) external view returns (BPool) {\n return pools[address(_marketFactory)][_marketId];\n }\n}\n" + }, + "contracts/balancer/BFactory.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is disstributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\n// Builds new BPools, logging their addresses and providing `isBPool(address) -> (bool)`\n\nimport \"./BPool.sol\";\n\ncontract BFactory is BBronze {\n event LOG_NEW_POOL(address indexed caller, address indexed pool);\n\n event LOG_BLABS(address indexed caller, address indexed blabs);\n\n mapping(address => bool) private _isBPool;\n\n function isBPool(address b) external view returns (bool) {\n return _isBPool[b];\n }\n\n function newBPool() external returns (BPool) {\n BPool bpool = new BPool();\n _isBPool[address(bpool)] = true;\n emit LOG_NEW_POOL(msg.sender, address(bpool));\n bpool.setController(msg.sender);\n return bpool;\n }\n\n address private _blabs;\n\n constructor() {\n _blabs = msg.sender;\n }\n\n function getBLabs() external view returns (address) {\n return _blabs;\n }\n\n function setBLabs(address b) external {\n require(msg.sender == _blabs, \"ERR_NOT_BLABS\");\n emit LOG_BLABS(msg.sender, b);\n _blabs = b;\n }\n\n function collect(BPool pool) external {\n require(msg.sender == _blabs, \"ERR_NOT_BLABS\");\n uint256 collected = IERC20Balancer(pool).balanceOf(address(this));\n bool xfer = pool.transfer(_blabs, collected);\n require(xfer, \"ERR_ERC20_FAILED\");\n }\n}\n" + }, + "contracts/libraries/SafeMathUint256.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\n/**\n * @title SafeMathUint256\n * @dev Uint256 math operations with safety checks that throw on error\n */\nlibrary SafeMathUint256 {\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n // assert(b > 0); // Solidity automatically throws when dividing by 0\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n return c;\n }\n\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n return a - b;\n }\n\n function subS(\n uint256 a,\n uint256 b,\n string memory message\n ) internal pure returns (uint256) {\n require(b <= a, message);\n return a - b;\n }\n\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n return c;\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a <= b) {\n return a;\n } else {\n return b;\n }\n }\n\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a >= b) {\n return a;\n } else {\n return b;\n }\n }\n\n function sqrt(uint256 y) internal pure returns (uint256 z) {\n if (y > 3) {\n uint256 x = (y + 1) / 2;\n z = y;\n while (x < z) {\n z = x;\n x = (y / x + x) / 2;\n }\n } else if (y != 0) {\n z = 1;\n }\n }\n\n function getUint256Min() internal pure returns (uint256) {\n return 0;\n }\n\n function getUint256Max() internal pure returns (uint256) {\n // 2 ** 256 - 1\n return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n }\n\n function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {\n return a % b == 0;\n }\n\n // Float [fixed point] Operations\n function fxpMul(\n uint256 a,\n uint256 b,\n uint256 base\n ) internal pure returns (uint256) {\n return div(mul(a, b), base);\n }\n\n function fxpDiv(\n uint256 a,\n uint256 b,\n uint256 base\n ) internal pure returns (uint256) {\n return div(mul(a, base), b);\n }\n}\n" + }, + "contracts/turbo/AbstractMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./TurboShareTokenFactory.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/Rewardable.sol\";\n\nabstract contract AbstractMarketFactoryV3 is TurboShareTokenFactory, Ownable, Rewardable {\n using SafeMathUint256 for uint256;\n\n event MarketCreated(uint256 id, string[] names, uint256[] initialOdds);\n event MarketResolved(uint256 id, address winner, uint256 winnerIndex, string winnerName);\n event MarketActivated(uint256 id);\n\n event SharesMinted(uint256 id, uint256 amount, address receiver);\n event SharesBurned(uint256 id, uint256 amount, address receiver);\n event WinningsClaimed(\n uint256 id,\n address winningOutcome,\n uint256 winningIndex,\n string winningName,\n uint256 amount,\n uint256 settlementFee,\n uint256 payout,\n address indexed receiver\n );\n\n IERC20Full public collateral;\n FeePot public feePot;\n\n // fees are out of 1e18 and only apply to new markets\n uint256 public stakerFee;\n uint256 public settlementFee;\n uint256 public protocolFee;\n\n address public protocol; // collects protocol fees\n\n uint256 public accumulatedProtocolFee = 0;\n // settlement address => amount of collateral\n mapping(address => uint256) public accumulatedSettlementFees;\n\n // How many shares equals one collateral.\n // Necessary to account for math errors from small numbers in balancer.\n // shares = collateral / shareFactor\n // collateral = shares * shareFactor\n uint256 public shareFactor;\n\n struct Market {\n address settlementAddress;\n OwnedERC20[] shareTokens;\n OwnedERC20 winner;\n uint256 winnerIndex;\n uint256 settlementFee;\n uint256 protocolFee;\n uint256 stakerFee;\n uint256 creationTimestamp;\n uint256 resolutionTimestamp; // when winner is declared\n uint256[] initialOdds;\n bool active; // false if not ready to use or if resolved\n }\n Market[] internal markets;\n\n uint256 private constant MAX_UINT = 2**256 - 1;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees, // staker, settlement, protocol\n address _protocol\n ) {\n owner = _owner; // controls fees for new markets\n collateral = _collateral;\n shareFactor = _shareFactor;\n feePot = _feePot;\n stakerFee = _fees[0];\n settlementFee = _fees[1];\n protocolFee = _fees[2];\n protocol = _protocol;\n\n _collateral.approve(address(_feePot), MAX_UINT);\n\n // First market is always empty so that marketid zero means \"no market\"\n markets.push(makeEmptyMarket());\n }\n\n // Returns an empty struct if the market doesn't exist.\n // Can check market existence before calling this by comparing _id against markets.length.\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\n function getMarket(uint256 _id) public view returns (Market memory) {\n if (_id >= markets.length) {\n return makeEmptyMarket();\n } else {\n return markets[_id];\n }\n }\n\n function marketCount() public view returns (uint256) {\n return markets.length;\n }\n\n // Returns factory-specific details about a market.\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\n\n function mintShares(\n uint256 _id,\n uint256 _shareToMint,\n address _receiver\n ) public {\n require(markets.length > _id);\n require(markets[_id].active);\n\n uint256 _cost = calcCost(_shareToMint);\n collateral.transferFrom(msg.sender, address(this), _cost);\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\n }\n\n emit SharesMinted(_id, _shareToMint, _receiver);\n }\n\n function burnShares(\n uint256 _id,\n uint256 _sharesToBurn,\n address _receiver\n ) public returns (uint256) {\n require(markets.length > _id);\n require(markets[_id].active);\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n // errors if sender doesn't have enough shares\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\n }\n\n uint256 _payout = calcCost(_sharesToBurn);\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\n\n accumulatedProtocolFee += _protocolFee;\n collateral.transfer(_receiver, _payout);\n feePot.depositFees(_stakerFee);\n\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\n return _payout;\n }\n\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\n require(isMarketResolved(_id), \"market unresolved\");\n\n Market memory _market = markets[_id];\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\n\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\n _payout = _payout.sub(_settlementFee);\n\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\n collateral.transfer(_receiver, _payout);\n\n uint256 _winningIndex = _market.winnerIndex;\n string memory _winningName = _market.winner.name();\n\n emit WinningsClaimed(\n _id,\n address(_market.winner),\n _winningIndex,\n _winningName,\n _winningShares,\n _settlementFee,\n _payout,\n _receiver\n );\n return _payout;\n }\n\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\n uint256 _totalWinnings = 0;\n for (uint256 i = 0; i < _ids.length; i++) {\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\n }\n return _totalWinnings;\n }\n\n function claimSettlementFees(address _receiver) public returns (uint256) {\n uint256 _fees = accumulatedSettlementFees[msg.sender];\n if (_fees > 0) {\n accumulatedSettlementFees[msg.sender] = 0;\n collateral.transfer(_receiver, _fees);\n }\n return _fees;\n }\n\n function claimProtocolFees() public returns (uint256) {\n require(msg.sender == protocol || msg.sender == address(this));\n uint256 _fees = accumulatedProtocolFee;\n if (_fees > 0) {\n accumulatedProtocolFee = 0;\n collateral.transfer(protocol, _fees);\n }\n return _fees;\n }\n\n function setSettlementFee(uint256 _newFee) external onlyOwner {\n settlementFee = _newFee;\n }\n\n function setStakerFee(uint256 _newFee) external onlyOwner {\n stakerFee = _newFee;\n }\n\n function setProtocolFee(uint256 _newFee) external onlyOwner {\n protocolFee = _newFee;\n }\n\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\n if (_claimFirst) {\n claimProtocolFees();\n }\n protocol = _newProtocol;\n }\n\n function startMarket(\n address _settlementAddress,\n string[] memory _names,\n uint256[] memory _initialOdds,\n bool _active\n ) internal returns (uint256 _marketId) {\n _marketId = markets.length;\n markets.push(\n Market(\n _settlementAddress,\n createShareTokens(_names, address(this)),\n OwnedERC20(0),\n 0,\n settlementFee,\n protocolFee,\n stakerFee,\n block.timestamp,\n 0,\n _initialOdds,\n _active\n )\n );\n emit MarketCreated(_marketId, _names, _initialOdds);\n if (_active) {\n emit MarketActivated(_marketId);\n }\n }\n\n function activateMarket(uint256 _marketId) internal {\n markets[_marketId].active = true;\n emit MarketActivated(_marketId);\n }\n\n function makeEmptyMarket() private pure returns (Market memory) {\n OwnedERC20[] memory _tokens = new OwnedERC20[](0);\n uint256[] memory _initialOdds = new uint256[](0);\n return Market(address(0), _tokens, OwnedERC20(0), 0, 0, 0, 0, 0, 0, _initialOdds, false);\n }\n\n function endMarket(uint256 _marketId, uint256 _winningOutcome) internal {\n Market storage _market = markets[_marketId];\n OwnedERC20 _winner = _market.shareTokens[_winningOutcome];\n\n _market.winner = _winner;\n _market.active = false;\n _market.winnerIndex = _winningOutcome;\n _market.resolutionTimestamp = block.timestamp;\n string memory _outcomeName = _winner.name();\n emit MarketResolved(_marketId, address(_winner), _winningOutcome, _outcomeName);\n }\n\n function isMarketResolved(uint256 _id) public view returns (bool) {\n Market memory _market = markets[_id];\n return _market.winner != OwnedERC20(0);\n }\n\n // shares => collateral\n // Shares must be both greater than (or equal to) and divisible by shareFactor.\n function calcCost(uint256 _shares) public view returns (uint256) {\n require(_shares >= shareFactor && _shares % shareFactor == 0);\n return _shares / shareFactor;\n }\n\n // collateral => shares\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\n return _collateralIn * shareFactor;\n }\n\n function onTransferOwnership(address, address) internal override {}\n}\n" + }, + "contracts/balancer/BPool.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BToken.sol\";\nimport \"./BMath.sol\";\n\ncontract BPool is BBronze, BToken, BMath {\n struct Record {\n bool bound; // is token bound to pool\n uint256 index; // private\n uint256 denorm; // denormalized weight\n uint256 balance;\n }\n\n event LOG_SWAP(\n address indexed caller,\n address indexed tokenIn,\n address indexed tokenOut,\n uint256 tokenAmountIn,\n uint256 tokenAmountOut\n );\n\n event LOG_JOIN(address indexed caller, address indexed tokenIn, uint256 tokenAmountIn);\n\n event LOG_EXIT(address indexed caller, address indexed tokenOut, uint256 tokenAmountOut);\n\n event LOG_CALL(bytes4 indexed sig, address indexed caller, bytes data) anonymous;\n\n modifier _logs_() {\n emit LOG_CALL(msg.sig, msg.sender, msg.data);\n _;\n }\n\n modifier _lock_() {\n require(!_mutex, \"ERR_REENTRY\");\n _mutex = true;\n _;\n _mutex = false;\n }\n\n modifier _viewlock_() {\n require(!_mutex, \"ERR_REENTRY\");\n _;\n }\n\n bool private _mutex;\n\n address private _factory; // BFactory address to push token exitFee to\n address private _controller; // has CONTROL role\n bool private _publicSwap; // true if PUBLIC can call SWAP functions\n\n // `setSwapFee` and `finalize` require CONTROL\n // `finalize` sets `PUBLIC can SWAP`, `PUBLIC can JOIN`\n uint256 private _swapFee;\n bool private _finalized;\n\n address[] private _tokens;\n mapping(address => Record) private _records;\n uint256 private _totalWeight;\n\n constructor() {\n _controller = msg.sender;\n _factory = msg.sender;\n _swapFee = MIN_FEE;\n _publicSwap = false;\n _finalized = false;\n }\n\n function isPublicSwap() external view returns (bool) {\n return _publicSwap;\n }\n\n function isFinalized() external view returns (bool) {\n return _finalized;\n }\n\n function isBound(address t) external view returns (bool) {\n return _records[t].bound;\n }\n\n function getNumTokens() external view returns (uint256) {\n return _tokens.length;\n }\n\n function getCurrentTokens() external view _viewlock_ returns (address[] memory tokens) {\n return _tokens;\n }\n\n function getFinalTokens() external view _viewlock_ returns (address[] memory tokens) {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n return _tokens;\n }\n\n function getDenormalizedWeight(address token) external view _viewlock_ returns (uint256) {\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n return _records[token].denorm;\n }\n\n function getTotalDenormalizedWeight() external view _viewlock_ returns (uint256) {\n return _totalWeight;\n }\n\n function getNormalizedWeight(address token) external view _viewlock_ returns (uint256) {\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n uint256 denorm = _records[token].denorm;\n return bdiv(denorm, _totalWeight);\n }\n\n function getBalance(address token) external view _viewlock_ returns (uint256) {\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n return _records[token].balance;\n }\n\n function getSwapFee() external view _viewlock_ returns (uint256) {\n return _swapFee;\n }\n\n function getController() external view _viewlock_ returns (address) {\n return _controller;\n }\n\n function setSwapFee(uint256 swapFee) external _logs_ _lock_ {\n require(!_finalized, \"ERR_IS_FINALIZED\");\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n require(swapFee >= MIN_FEE, \"ERR_MIN_FEE\");\n require(swapFee <= MAX_FEE, \"ERR_MAX_FEE\");\n _swapFee = swapFee;\n }\n\n function setController(address manager) external _logs_ _lock_ {\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n _controller = manager;\n }\n\n function setPublicSwap(bool public_) external _logs_ _lock_ {\n require(!_finalized, \"ERR_IS_FINALIZED\");\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n _publicSwap = public_;\n }\n\n function finalize() external _logs_ _lock_ {\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n require(!_finalized, \"ERR_IS_FINALIZED\");\n require(_tokens.length >= MIN_BOUND_TOKENS, \"ERR_MIN_TOKENS\");\n\n _finalized = true;\n _publicSwap = true;\n\n _mintPoolShare(INIT_POOL_SUPPLY);\n _pushPoolShare(msg.sender, INIT_POOL_SUPPLY);\n }\n\n function bind(\n address token,\n uint256 balance,\n uint256 denorm\n )\n external\n _logs_ // _lock_ Bind does not lock because it jumps to `rebind`, which does\n {\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n require(!_records[token].bound, \"ERR_IS_BOUND\");\n require(!_finalized, \"ERR_IS_FINALIZED\");\n\n require(_tokens.length < MAX_BOUND_TOKENS, \"ERR_MAX_TOKENS\");\n\n _records[token] = Record({\n bound: true,\n index: _tokens.length,\n denorm: 0, // balance and denorm will be validated\n balance: 0 // and set by `rebind`\n });\n _tokens.push(token);\n rebind(token, balance, denorm);\n }\n\n function rebind(\n address token,\n uint256 balance,\n uint256 denorm\n ) public _logs_ _lock_ {\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n require(!_finalized, \"ERR_IS_FINALIZED\");\n\n require(denorm >= MIN_WEIGHT, \"ERR_MIN_WEIGHT\");\n require(denorm <= MAX_WEIGHT, \"ERR_MAX_WEIGHT\");\n require(balance >= MIN_BALANCE, \"ERR_MIN_BALANCE\");\n\n // Adjust the denorm and totalWeight\n uint256 oldWeight = _records[token].denorm;\n if (denorm > oldWeight) {\n _totalWeight = badd(_totalWeight, bsub(denorm, oldWeight));\n require(_totalWeight <= MAX_TOTAL_WEIGHT, \"ERR_MAX_TOTAL_WEIGHT\");\n } else if (denorm < oldWeight) {\n _totalWeight = bsub(_totalWeight, bsub(oldWeight, denorm));\n }\n _records[token].denorm = denorm;\n\n // Adjust the balance record and actual token balance\n uint256 oldBalance = _records[token].balance;\n _records[token].balance = balance;\n if (balance > oldBalance) {\n _pullUnderlying(token, msg.sender, bsub(balance, oldBalance));\n } else if (balance < oldBalance) {\n // In this case liquidity is being withdrawn, so charge EXIT_FEE\n uint256 tokenBalanceWithdrawn = bsub(oldBalance, balance);\n uint256 tokenExitFee = bmul(tokenBalanceWithdrawn, EXIT_FEE);\n _pushUnderlying(token, msg.sender, bsub(tokenBalanceWithdrawn, tokenExitFee));\n _pushUnderlying(token, _factory, tokenExitFee);\n }\n }\n\n function unbind(address token) external _logs_ _lock_ {\n require(msg.sender == _controller, \"ERR_NOT_CONTROLLER\");\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n require(!_finalized, \"ERR_IS_FINALIZED\");\n\n uint256 tokenBalance = _records[token].balance;\n uint256 tokenExitFee = bmul(tokenBalance, EXIT_FEE);\n\n _totalWeight = bsub(_totalWeight, _records[token].denorm);\n\n // Swap the token-to-unbind with the last token,\n // then delete the last token\n uint256 index = _records[token].index;\n uint256 last = _tokens.length - 1;\n _tokens[index] = _tokens[last];\n _records[_tokens[index]].index = index;\n _tokens.pop();\n _records[token] = Record({bound: false, index: 0, denorm: 0, balance: 0});\n\n _pushUnderlying(token, msg.sender, bsub(tokenBalance, tokenExitFee));\n _pushUnderlying(token, _factory, tokenExitFee);\n }\n\n // Absorb any tokens that have been sent to this contract into the pool\n function gulp(address token) external _logs_ _lock_ {\n require(_records[token].bound, \"ERR_NOT_BOUND\");\n _records[token].balance = IERC20Balancer(token).balanceOf(address(this));\n }\n\n function getSpotPrice(address tokenIn, address tokenOut) external view _viewlock_ returns (uint256 spotPrice) {\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n Record storage inRecord = _records[tokenIn];\n Record storage outRecord = _records[tokenOut];\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\n }\n\n function getSpotPriceSansFee(address tokenIn, address tokenOut)\n external\n view\n _viewlock_\n returns (uint256 spotPrice)\n {\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n Record storage inRecord = _records[tokenIn];\n Record storage outRecord = _records[tokenOut];\n return calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, 0);\n }\n\n function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external _logs_ _lock_ {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n\n uint256 poolTotal = totalSupply();\n uint256 ratio = bdiv(poolAmountOut, poolTotal);\n require(ratio != 0, \"ERR_MATH_APPROX\");\n\n for (uint256 i = 0; i < _tokens.length; i++) {\n address t = _tokens[i];\n uint256 bal = _records[t].balance;\n uint256 tokenAmountIn = bmul(ratio, bal);\n require(tokenAmountIn != 0, \"ERR_MATH_APPROX\");\n require(tokenAmountIn <= maxAmountsIn[i], \"ERR_LIMIT_IN\");\n _records[t].balance = badd(_records[t].balance, tokenAmountIn);\n emit LOG_JOIN(msg.sender, t, tokenAmountIn);\n _pullUnderlying(t, msg.sender, tokenAmountIn);\n }\n _mintPoolShare(poolAmountOut);\n _pushPoolShare(msg.sender, poolAmountOut);\n }\n\n function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external _logs_ _lock_ {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n\n uint256 poolTotal = totalSupply();\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\n require(ratio != 0, \"ERR_MATH_APPROX\");\n\n _pullPoolShare(msg.sender, poolAmountIn);\n _pushPoolShare(_factory, exitFee);\n _burnPoolShare(pAiAfterExitFee);\n\n for (uint256 i = 0; i < _tokens.length; i++) {\n address t = _tokens[i];\n uint256 bal = _records[t].balance;\n uint256 tokenAmountOut = bmul(ratio, bal);\n require(tokenAmountOut != 0, \"ERR_MATH_APPROX\");\n require(tokenAmountOut >= minAmountsOut[i], \"ERR_LIMIT_OUT\");\n _records[t].balance = bsub(_records[t].balance, tokenAmountOut);\n emit LOG_EXIT(msg.sender, t, tokenAmountOut);\n _pushUnderlying(t, msg.sender, tokenAmountOut);\n }\n }\n\n function calcExitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut)\n external\n view\n returns (uint256[] memory)\n {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n\n uint256 poolTotal = totalSupply();\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\n uint256 pAiAfterExitFee = bsub(poolAmountIn, exitFee);\n uint256 ratio = bdiv(pAiAfterExitFee, poolTotal);\n\n uint256[] memory _amounts = new uint256[](_tokens.length * 2);\n\n for (uint256 i = 0; i < _tokens.length; i++) {\n address t = _tokens[i];\n uint256 bal = _records[t].balance;\n\n _amounts[i] = bmul(ratio, bal);\n _amounts[_tokens.length + i] = minAmountsOut[i];\n require(_amounts[i] >= minAmountsOut[i], \"ERR_LIMIT_OUT\");\n }\n\n return _amounts;\n }\n\n function swapExactAmountIn(\n address tokenIn,\n uint256 tokenAmountIn,\n address tokenOut,\n uint256 minAmountOut,\n uint256 maxPrice\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut, uint256 spotPriceAfter) {\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n require(_publicSwap, \"ERR_SWAP_NOT_PUBLIC\");\n\n Record storage inRecord = _records[address(tokenIn)];\n Record storage outRecord = _records[address(tokenOut)];\n\n require(tokenAmountIn <= bmul(inRecord.balance, MAX_IN_RATIO), \"ERR_MAX_IN_RATIO\");\n\n uint256 spotPriceBefore =\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\n require(spotPriceBefore <= maxPrice, \"ERR_BAD_LIMIT_PRICE\");\n\n tokenAmountOut = calcOutGivenIn(\n inRecord.balance,\n inRecord.denorm,\n outRecord.balance,\n outRecord.denorm,\n tokenAmountIn,\n _swapFee\n );\n require(tokenAmountOut >= minAmountOut, \"ERR_LIMIT_OUT\");\n\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\n\n spotPriceAfter = calcSpotPrice(\n inRecord.balance,\n inRecord.denorm,\n outRecord.balance,\n outRecord.denorm,\n _swapFee\n );\n require(spotPriceAfter >= spotPriceBefore, \"ERR_MATH_APPROX\");\n require(spotPriceAfter <= maxPrice, \"ERR_LIMIT_PRICE\");\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \"ERR_MATH_APPROX\");\n\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\n\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\n\n return (tokenAmountOut, spotPriceAfter);\n }\n\n function swapExactAmountOut(\n address tokenIn,\n uint256 maxAmountIn,\n address tokenOut,\n uint256 tokenAmountOut,\n uint256 maxPrice\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn, uint256 spotPriceAfter) {\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n require(_publicSwap, \"ERR_SWAP_NOT_PUBLIC\");\n\n Record storage inRecord = _records[address(tokenIn)];\n Record storage outRecord = _records[address(tokenOut)];\n\n require(tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO), \"ERR_MAX_OUT_RATIO\");\n\n uint256 spotPriceBefore =\n calcSpotPrice(inRecord.balance, inRecord.denorm, outRecord.balance, outRecord.denorm, _swapFee);\n require(spotPriceBefore <= maxPrice, \"ERR_BAD_LIMIT_PRICE\");\n\n tokenAmountIn = calcInGivenOut(\n inRecord.balance,\n inRecord.denorm,\n outRecord.balance,\n outRecord.denorm,\n tokenAmountOut,\n _swapFee\n );\n require(tokenAmountIn <= maxAmountIn, \"ERR_LIMIT_IN\");\n\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\n\n spotPriceAfter = calcSpotPrice(\n inRecord.balance,\n inRecord.denorm,\n outRecord.balance,\n outRecord.denorm,\n _swapFee\n );\n require(spotPriceAfter >= spotPriceBefore, \"ERR_MATH_APPROX\");\n require(spotPriceAfter <= maxPrice, \"ERR_LIMIT_PRICE\");\n require(spotPriceBefore <= bdiv(tokenAmountIn, tokenAmountOut), \"ERR_MATH_APPROX\");\n\n emit LOG_SWAP(msg.sender, tokenIn, tokenOut, tokenAmountIn, tokenAmountOut);\n\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\n\n return (tokenAmountIn, spotPriceAfter);\n }\n\n function joinswapExternAmountIn(\n address tokenIn,\n uint256 tokenAmountIn,\n uint256 minPoolAmountOut\n ) external _logs_ _lock_ returns (uint256 poolAmountOut) {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \"ERR_MAX_IN_RATIO\");\n\n Record storage inRecord = _records[tokenIn];\n\n poolAmountOut = calcPoolOutGivenSingleIn(\n inRecord.balance,\n inRecord.denorm,\n _totalSupply,\n _totalWeight,\n tokenAmountIn,\n _swapFee\n );\n\n require(poolAmountOut >= minPoolAmountOut, \"ERR_LIMIT_OUT\");\n\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\n\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\n\n _mintPoolShare(poolAmountOut);\n _pushPoolShare(msg.sender, poolAmountOut);\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\n\n return poolAmountOut;\n }\n\n function joinswapPoolAmountOut(\n address tokenIn,\n uint256 poolAmountOut,\n uint256 maxAmountIn\n ) external _logs_ _lock_ returns (uint256 tokenAmountIn) {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n require(_records[tokenIn].bound, \"ERR_NOT_BOUND\");\n\n Record storage inRecord = _records[tokenIn];\n\n tokenAmountIn = calcSingleInGivenPoolOut(\n inRecord.balance,\n inRecord.denorm,\n _totalSupply,\n _totalWeight,\n poolAmountOut,\n _swapFee\n );\n\n require(tokenAmountIn != 0, \"ERR_MATH_APPROX\");\n require(tokenAmountIn <= maxAmountIn, \"ERR_LIMIT_IN\");\n\n require(tokenAmountIn <= bmul(_records[tokenIn].balance, MAX_IN_RATIO), \"ERR_MAX_IN_RATIO\");\n\n inRecord.balance = badd(inRecord.balance, tokenAmountIn);\n\n emit LOG_JOIN(msg.sender, tokenIn, tokenAmountIn);\n\n _mintPoolShare(poolAmountOut);\n _pushPoolShare(msg.sender, poolAmountOut);\n _pullUnderlying(tokenIn, msg.sender, tokenAmountIn);\n\n return tokenAmountIn;\n }\n\n function exitswapPoolAmountIn(\n address tokenOut,\n uint256 poolAmountIn,\n uint256 minAmountOut\n ) external _logs_ _lock_ returns (uint256 tokenAmountOut) {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n\n Record storage outRecord = _records[tokenOut];\n\n tokenAmountOut = calcSingleOutGivenPoolIn(\n outRecord.balance,\n outRecord.denorm,\n _totalSupply,\n _totalWeight,\n poolAmountIn,\n _swapFee\n );\n\n require(tokenAmountOut >= minAmountOut, \"ERR_LIMIT_OUT\");\n\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \"ERR_MAX_OUT_RATIO\");\n\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\n\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\n\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\n\n _pullPoolShare(msg.sender, poolAmountIn);\n _burnPoolShare(bsub(poolAmountIn, exitFee));\n _pushPoolShare(_factory, exitFee);\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\n\n return tokenAmountOut;\n }\n\n function exitswapExternAmountOut(\n address tokenOut,\n uint256 tokenAmountOut,\n uint256 maxPoolAmountIn\n ) external _logs_ _lock_ returns (uint256 poolAmountIn) {\n require(_finalized, \"ERR_NOT_FINALIZED\");\n require(_records[tokenOut].bound, \"ERR_NOT_BOUND\");\n require(tokenAmountOut <= bmul(_records[tokenOut].balance, MAX_OUT_RATIO), \"ERR_MAX_OUT_RATIO\");\n\n Record storage outRecord = _records[tokenOut];\n\n poolAmountIn = calcPoolInGivenSingleOut(\n outRecord.balance,\n outRecord.denorm,\n _totalSupply,\n _totalWeight,\n tokenAmountOut,\n _swapFee\n );\n\n require(poolAmountIn != 0, \"ERR_MATH_APPROX\");\n require(poolAmountIn <= maxPoolAmountIn, \"ERR_LIMIT_IN\");\n\n outRecord.balance = bsub(outRecord.balance, tokenAmountOut);\n\n uint256 exitFee = bmul(poolAmountIn, EXIT_FEE);\n\n emit LOG_EXIT(msg.sender, tokenOut, tokenAmountOut);\n\n _pullPoolShare(msg.sender, poolAmountIn);\n _burnPoolShare(bsub(poolAmountIn, exitFee));\n _pushPoolShare(_factory, exitFee);\n _pushUnderlying(tokenOut, msg.sender, tokenAmountOut);\n\n return poolAmountIn;\n }\n\n // ==\n // 'Underlying' token-manipulation functions make external calls but are NOT locked\n // You must `_lock_` or otherwise ensure reentry-safety\n\n function _pullUnderlying(\n address erc20,\n address from,\n uint256 amount\n ) internal {\n bool xfer = IERC20Balancer(erc20).transferFrom(from, address(this), amount);\n require(xfer, \"ERR_ERC20_FALSE\");\n }\n\n function _pushUnderlying(\n address erc20,\n address to,\n uint256 amount\n ) internal {\n bool xfer = IERC20Balancer(erc20).transfer(to, amount);\n require(xfer, \"ERR_ERC20_FALSE\");\n }\n\n function _pullPoolShare(address from, uint256 amount) internal {\n _pull(from, amount);\n }\n\n function _pushPoolShare(address to, uint256 amount) internal {\n _push(to, amount);\n }\n\n function _mintPoolShare(uint256 amount) internal {\n _mint(amount);\n }\n\n function _burnPoolShare(uint256 amount) internal {\n _burn(amount);\n }\n}\n" + }, + "contracts/balancer/BToken.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BNum.sol\";\n\ninterface IERC20Balancer {\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address whom) external view returns (uint256);\n\n function allowance(address src, address dst) external view returns (uint256);\n\n function approve(address dst, uint256 amt) external returns (bool);\n\n function transfer(address dst, uint256 amt) external returns (bool);\n\n function transferFrom(\n address src,\n address dst,\n uint256 amt\n ) external returns (bool);\n}\n\ncontract BTokenBase is BNum {\n mapping(address => uint256) internal _balance;\n mapping(address => mapping(address => uint256)) internal _allowance;\n uint256 internal _totalSupply;\n\n event Approval(address indexed src, address indexed dst, uint256 amt);\n event Transfer(address indexed src, address indexed dst, uint256 amt);\n\n function _mint(uint256 amt) internal {\n _balance[address(this)] = badd(_balance[address(this)], amt);\n _totalSupply = badd(_totalSupply, amt);\n emit Transfer(address(0), address(this), amt);\n }\n\n function _burn(uint256 amt) internal {\n require(_balance[address(this)] >= amt, \"ERR_INSUFFICIENT_BAL\");\n _balance[address(this)] = bsub(_balance[address(this)], amt);\n _totalSupply = bsub(_totalSupply, amt);\n emit Transfer(address(this), address(0), amt);\n }\n\n function _move(\n address src,\n address dst,\n uint256 amt\n ) internal {\n require(_balance[src] >= amt, \"ERR_INSUFFICIENT_BAL\");\n _balance[src] = bsub(_balance[src], amt);\n _balance[dst] = badd(_balance[dst], amt);\n emit Transfer(src, dst, amt);\n }\n\n function _push(address to, uint256 amt) internal {\n _move(address(this), to, amt);\n }\n\n function _pull(address from, uint256 amt) internal {\n _move(from, address(this), amt);\n }\n}\n\ncontract BToken is BTokenBase, IERC20Balancer {\n string private _name = \"Balancer Pool Token\";\n string private _symbol = \"BPT\";\n uint8 private _decimals = 18;\n\n function name() public view returns (string memory) {\n return _name;\n }\n\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n function allowance(address src, address dst) external view override returns (uint256) {\n return _allowance[src][dst];\n }\n\n function balanceOf(address whom) external view override returns (uint256) {\n return _balance[whom];\n }\n\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n function approve(address dst, uint256 amt) external override returns (bool) {\n _allowance[msg.sender][dst] = amt;\n emit Approval(msg.sender, dst, amt);\n return true;\n }\n\n function increaseApproval(address dst, uint256 amt) external returns (bool) {\n _allowance[msg.sender][dst] = badd(_allowance[msg.sender][dst], amt);\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\n return true;\n }\n\n function decreaseApproval(address dst, uint256 amt) external returns (bool) {\n uint256 oldValue = _allowance[msg.sender][dst];\n if (amt > oldValue) {\n _allowance[msg.sender][dst] = 0;\n } else {\n _allowance[msg.sender][dst] = bsub(oldValue, amt);\n }\n emit Approval(msg.sender, dst, _allowance[msg.sender][dst]);\n return true;\n }\n\n function transfer(address dst, uint256 amt) external override returns (bool) {\n _move(msg.sender, dst, amt);\n return true;\n }\n\n function transferFrom(\n address src,\n address dst,\n uint256 amt\n ) external override returns (bool) {\n require(msg.sender == src || amt <= _allowance[src][msg.sender], \"ERR_BTOKEN_BAD_CALLER\");\n _move(src, dst, amt);\n if (msg.sender != src && _allowance[src][msg.sender] != uint256(-1)) {\n _allowance[src][msg.sender] = bsub(_allowance[src][msg.sender], amt);\n emit Approval(msg.sender, dst, _allowance[src][msg.sender]);\n }\n return true;\n }\n}\n" + }, + "contracts/balancer/BMath.sol": { + "content": "// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program. If not, see .\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BNum.sol\";\n\ncontract BMath is BBronze, BConst, BNum {\n /**********************************************************************************************\n // calcSpotPrice //\n // sP = spotPrice //\n // bI = tokenBalanceIn ( bI / wI ) 1 //\n // bO = tokenBalanceOut sP = ----------- * ---------- //\n // wI = tokenWeightIn ( bO / wO ) ( 1 - sF ) //\n // wO = tokenWeightOut //\n // sF = swapFee //\n **********************************************************************************************/\n function calcSpotPrice(\n uint256 tokenBalanceIn,\n uint256 tokenWeightIn,\n uint256 tokenBalanceOut,\n uint256 tokenWeightOut,\n uint256 swapFee\n ) public pure returns (uint256 spotPrice) {\n uint256 numer = bdiv(tokenBalanceIn, tokenWeightIn);\n uint256 denom = bdiv(tokenBalanceOut, tokenWeightOut);\n uint256 ratio = bdiv(numer, denom);\n uint256 scale = bdiv(BONE, bsub(BONE, swapFee));\n return (spotPrice = bmul(ratio, scale));\n }\n\n /**********************************************************************************************\n // calcOutGivenIn //\n // aO = tokenAmountOut //\n // bO = tokenBalanceOut //\n // bI = tokenBalanceIn / / bI \\ (wI / wO) \\ //\n // aI = tokenAmountIn aO = bO * | 1 - | -------------------------- | ^ | //\n // wI = tokenWeightIn \\ \\ ( bI + ( aI * ( 1 - sF )) / / //\n // wO = tokenWeightOut //\n // sF = swapFee //\n **********************************************************************************************/\n function calcOutGivenIn(\n uint256 tokenBalanceIn,\n uint256 tokenWeightIn,\n uint256 tokenBalanceOut,\n uint256 tokenWeightOut,\n uint256 tokenAmountIn,\n uint256 swapFee\n ) public pure returns (uint256 tokenAmountOut) {\n uint256 weightRatio = bdiv(tokenWeightIn, tokenWeightOut);\n uint256 adjustedIn = bsub(BONE, swapFee);\n adjustedIn = bmul(tokenAmountIn, adjustedIn);\n uint256 y = bdiv(tokenBalanceIn, badd(tokenBalanceIn, adjustedIn));\n uint256 foo = bpow(y, weightRatio);\n uint256 bar = bsub(BONE, foo);\n tokenAmountOut = bmul(tokenBalanceOut, bar);\n return tokenAmountOut;\n }\n\n /**********************************************************************************************\n // calcInGivenOut //\n // aI = tokenAmountIn //\n // bO = tokenBalanceOut / / bO \\ (wO / wI) \\ //\n // bI = tokenBalanceIn bI * | | ------------ | ^ - 1 | //\n // aO = tokenAmountOut aI = \\ \\ ( bO - aO ) / / //\n // wI = tokenWeightIn -------------------------------------------- //\n // wO = tokenWeightOut ( 1 - sF ) //\n // sF = swapFee //\n **********************************************************************************************/\n function calcInGivenOut(\n uint256 tokenBalanceIn,\n uint256 tokenWeightIn,\n uint256 tokenBalanceOut,\n uint256 tokenWeightOut,\n uint256 tokenAmountOut,\n uint256 swapFee\n ) public pure returns (uint256 tokenAmountIn) {\n uint256 weightRatio = bdiv(tokenWeightOut, tokenWeightIn);\n uint256 diff = bsub(tokenBalanceOut, tokenAmountOut);\n uint256 y = bdiv(tokenBalanceOut, diff);\n uint256 foo = bpow(y, weightRatio);\n foo = bsub(foo, BONE);\n tokenAmountIn = bsub(BONE, swapFee);\n tokenAmountIn = bdiv(bmul(tokenBalanceIn, foo), tokenAmountIn);\n return tokenAmountIn;\n }\n\n /**********************************************************************************************\n // calcPoolOutGivenSingleIn //\n // pAo = poolAmountOut / \\ //\n // tAi = tokenAmountIn /// / // wI \\ \\\\ \\ wI \\ //\n // wI = tokenWeightIn //| tAi *| 1 - || 1 - -- | * sF || + tBi \\ -- \\ //\n // tW = totalWeight pAo=|| \\ \\ \\\\ tW / // | ^ tW | * pS - pS //\n // tBi = tokenBalanceIn \\\\ ------------------------------------- / / //\n // pS = poolSupply \\\\ tBi / / //\n // sF = swapFee \\ / //\n **********************************************************************************************/\n\n // Charge the trading fee for the proportion of tokenAi\n /// which is implicitly traded to the other pool tokens.\n // That proportion is (1- weightTokenIn)\n // tokenAiAfterFee = tAi * (1 - (1-weightTi) * poolFee);\n\n function calcPoolOutGivenSingleIn(\n uint256 tokenBalanceIn,\n uint256 tokenWeightIn,\n uint256 poolSupply,\n uint256 totalWeight,\n uint256 tokenAmountIn,\n uint256 swapFee\n ) public pure returns (uint256 poolAmountOut) {\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\n uint256 tokenAmountInAfterFee = bmul(tokenAmountIn, bsub(BONE, zaz));\n\n uint256 newTokenBalanceIn = badd(tokenBalanceIn, tokenAmountInAfterFee);\n uint256 tokenInRatio = bdiv(newTokenBalanceIn, tokenBalanceIn);\n\n // uint newPoolSupply = (ratioTi ^ weightTi) * poolSupply;\n uint256 poolRatio = bpow(tokenInRatio, normalizedWeight);\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\n poolAmountOut = bsub(newPoolSupply, poolSupply);\n return poolAmountOut;\n }\n\n /**********************************************************************************************\n // calcSingleInGivenPoolOut //\n // tAi = tokenAmountIn //(pS + pAo)\\ / 1 \\\\ //\n // pS = poolSupply || --------- | ^ | --------- || * bI - bI //\n // pAo = poolAmountOut \\\\ pS / \\(wI / tW)// //\n // bI = balanceIn tAi = -------------------------------------------- //\n // wI = weightIn / wI \\ //\n // tW = totalWeight | 1 - ---- | * sF //\n // sF = swapFee \\ tW / //\n **********************************************************************************************/\n function calcSingleInGivenPoolOut(\n uint256 tokenBalanceIn,\n uint256 tokenWeightIn,\n uint256 poolSupply,\n uint256 totalWeight,\n uint256 poolAmountOut,\n uint256 swapFee\n ) public pure returns (uint256 tokenAmountIn) {\n uint256 normalizedWeight = bdiv(tokenWeightIn, totalWeight);\n uint256 newPoolSupply = badd(poolSupply, poolAmountOut);\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\n\n //uint newBalTi = poolRatio^(1/weightTi) * balTi;\n uint256 boo = bdiv(BONE, normalizedWeight);\n uint256 tokenInRatio = bpow(poolRatio, boo);\n uint256 newTokenBalanceIn = bmul(tokenInRatio, tokenBalanceIn);\n uint256 tokenAmountInAfterFee = bsub(newTokenBalanceIn, tokenBalanceIn);\n // Do reverse order of fees charged in joinswap_ExternAmountIn, this way\n // ``` pAo == joinswap_ExternAmountIn(Ti, joinswap_PoolAmountOut(pAo, Ti)) ```\n //uint tAi = tAiAfterFee / (1 - (1-weightTi) * swapFee) ;\n uint256 zar = bmul(bsub(BONE, normalizedWeight), swapFee);\n tokenAmountIn = bdiv(tokenAmountInAfterFee, bsub(BONE, zar));\n return tokenAmountIn;\n }\n\n /**********************************************************************************************\n // calcSingleOutGivenPoolIn //\n // tAo = tokenAmountOut / / \\\\ //\n // bO = tokenBalanceOut / // pS - (pAi * (1 - eF)) \\ / 1 \\ \\\\ //\n // pAi = poolAmountIn | bO - || ----------------------- | ^ | --------- | * b0 || //\n // ps = poolSupply \\ \\\\ pS / \\(wO / tW)/ // //\n // wI = tokenWeightIn tAo = \\ \\ // //\n // tW = totalWeight / / wO \\ \\ //\n // sF = swapFee * | 1 - | 1 - ---- | * sF | //\n // eF = exitFee \\ \\ tW / / //\n **********************************************************************************************/\n function calcSingleOutGivenPoolIn(\n uint256 tokenBalanceOut,\n uint256 tokenWeightOut,\n uint256 poolSupply,\n uint256 totalWeight,\n uint256 poolAmountIn,\n uint256 swapFee\n ) public pure returns (uint256 tokenAmountOut) {\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\n // charge exit fee on the pool token side\n // pAiAfterExitFee = pAi*(1-exitFee)\n uint256 poolAmountInAfterExitFee = bmul(poolAmountIn, bsub(BONE, EXIT_FEE));\n uint256 newPoolSupply = bsub(poolSupply, poolAmountInAfterExitFee);\n uint256 poolRatio = bdiv(newPoolSupply, poolSupply);\n\n // newBalTo = poolRatio^(1/weightTo) * balTo;\n uint256 tokenOutRatio = bpow(poolRatio, bdiv(BONE, normalizedWeight));\n uint256 newTokenBalanceOut = bmul(tokenOutRatio, tokenBalanceOut);\n\n uint256 tokenAmountOutBeforeSwapFee = bsub(tokenBalanceOut, newTokenBalanceOut);\n\n // charge swap fee on the output token side\n //uint tAo = tAoBeforeSwapFee * (1 - (1-weightTo) * swapFee)\n uint256 zaz = bmul(bsub(BONE, normalizedWeight), swapFee);\n tokenAmountOut = bmul(tokenAmountOutBeforeSwapFee, bsub(BONE, zaz));\n return tokenAmountOut;\n }\n\n /**********************************************************************************************\n // calcPoolInGivenSingleOut //\n // pAi = poolAmountIn // / tAo \\\\ / wO \\ \\ //\n // bO = tokenBalanceOut // | bO - -------------------------- |\\ | ---- | \\ //\n // tAo = tokenAmountOut pS - || \\ 1 - ((1 - (tO / tW)) * sF)/ | ^ \\ tW / * pS | //\n // ps = poolSupply \\\\ -----------------------------------/ / //\n // wO = tokenWeightOut pAi = \\\\ bO / / //\n // tW = totalWeight ------------------------------------------------------------- //\n // sF = swapFee ( 1 - eF ) //\n // eF = exitFee //\n **********************************************************************************************/\n function calcPoolInGivenSingleOut(\n uint256 tokenBalanceOut,\n uint256 tokenWeightOut,\n uint256 poolSupply,\n uint256 totalWeight,\n uint256 tokenAmountOut,\n uint256 swapFee\n ) public pure returns (uint256 poolAmountIn) {\n // charge swap fee on the output token side\n uint256 normalizedWeight = bdiv(tokenWeightOut, totalWeight);\n //uint tAoBeforeSwapFee = tAo / (1 - (1-weightTo) * swapFee) ;\n uint256 zoo = bsub(BONE, normalizedWeight);\n uint256 zar = bmul(zoo, swapFee);\n uint256 tokenAmountOutBeforeSwapFee = bdiv(tokenAmountOut, bsub(BONE, zar));\n\n uint256 newTokenBalanceOut = bsub(tokenBalanceOut, tokenAmountOutBeforeSwapFee);\n uint256 tokenOutRatio = bdiv(newTokenBalanceOut, tokenBalanceOut);\n\n //uint newPoolSupply = (ratioTo ^ weightTo) * poolSupply;\n uint256 poolRatio = bpow(tokenOutRatio, normalizedWeight);\n uint256 newPoolSupply = bmul(poolRatio, poolSupply);\n uint256 poolAmountInAfterExitFee = bsub(poolSupply, newPoolSupply);\n\n // charge exit fee on the pool token side\n // pAi = pAiAfterExitFee/(1-exitFee)\n poolAmountIn = bdiv(poolAmountInAfterExitFee, bsub(BONE, EXIT_FEE));\n return poolAmountIn;\n }\n}\n" + }, + "contracts/libraries/IERC20Full.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IERC20Full is IERC20 {\n function name() external view returns (string memory);\n\n function symbol() external view returns (string memory);\n\n function decimals() external view returns (uint8);\n}\n" + }, + "contracts/turbo/TurboShareTokenFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./OwnedShareToken.sol\";\n\nabstract contract TurboShareTokenFactory {\n function createShareTokens(string[] memory _names, address _owner) internal returns (OwnedERC20[] memory) {\n uint256 _numOutcomes = _names.length;\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\n\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\n _tokens[_i] = new OwnedERC20(_names[_i], _names[_i], _owner);\n }\n return _tokens;\n }\n}\n\nabstract contract TurboShareTokenFactoryV1 {\n function createShareTokens(\n string[] memory _names,\n string[] memory _symbols,\n address _owner\n ) internal returns (OwnedERC20[] memory) {\n uint256 _numOutcomes = _names.length;\n OwnedERC20[] memory _tokens = new OwnedERC20[](_numOutcomes);\n\n for (uint256 _i = 0; _i < _numOutcomes; _i++) {\n _tokens[_i] = new OwnedERC20(_names[_i], _symbols[_i], _owner);\n }\n return _tokens;\n }\n}\n" + }, + "contracts/turbo/FeePot.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../libraries/SafeMathUint256.sol\";\nimport \"../libraries/IERC20Full.sol\";\n\ncontract FeePot is ERC20 {\n using SafeMathUint256 for uint256;\n\n uint256 internal constant magnitude = 2**128;\n\n IERC20Full public collateral;\n IERC20Full public reputationToken;\n\n uint256 public magnifiedFeesPerShare;\n\n mapping(address => uint256) public magnifiedFeesCorrections;\n mapping(address => uint256) public storedFees;\n\n uint256 public feeReserve;\n\n constructor(IERC20Full _collateral, IERC20Full _reputationToken)\n ERC20(\n string(abi.encodePacked(\"S_\", _reputationToken.symbol())),\n string(abi.encodePacked(\"S_\", _reputationToken.symbol()))\n )\n {\n collateral = _collateral;\n reputationToken = _reputationToken;\n\n require(_collateral != IERC20Full(0));\n }\n\n function depositFees(uint256 _amount) public returns (bool) {\n collateral.transferFrom(msg.sender, address(this), _amount);\n uint256 _totalSupply = totalSupply(); // after collateral.transferFrom to prevent reentrancy causing stale totalSupply\n if (_totalSupply == 0) {\n feeReserve = feeReserve.add(_amount);\n return true;\n }\n if (feeReserve > 0) {\n _amount = _amount.add(feeReserve);\n feeReserve = 0;\n }\n magnifiedFeesPerShare = magnifiedFeesPerShare.add((_amount).mul(magnitude) / _totalSupply);\n return true;\n }\n\n function withdrawableFeesOf(address _owner) public view returns (uint256) {\n return earnedFeesOf(_owner).add(storedFees[_owner]);\n }\n\n function earnedFeesOf(address _owner) public view returns (uint256) {\n uint256 _ownerBalance = balanceOf(_owner);\n uint256 _magnifiedFees = magnifiedFeesPerShare.mul(_ownerBalance);\n return _magnifiedFees.sub(magnifiedFeesCorrections[_owner]) / magnitude;\n }\n\n function _transfer(\n address _from,\n address _to,\n uint256 _amount\n ) internal override {\n storedFees[_from] = storedFees[_from].add(earnedFeesOf(_from));\n super._transfer(_from, _to, _amount);\n\n magnifiedFeesCorrections[_from] = magnifiedFeesPerShare.mul(balanceOf(_from));\n magnifiedFeesCorrections[_to] = magnifiedFeesCorrections[_to].add(magnifiedFeesPerShare.mul(_amount));\n }\n\n function stake(uint256 _amount) external returns (bool) {\n reputationToken.transferFrom(msg.sender, address(this), _amount);\n _mint(msg.sender, _amount);\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesCorrections[msg.sender].add(\n magnifiedFeesPerShare.mul(_amount)\n );\n return true;\n }\n\n function exit(uint256 _amount) external returns (bool) {\n redeemInternal(msg.sender);\n _burn(msg.sender, _amount);\n reputationToken.transfer(msg.sender, _amount);\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\n return true;\n }\n\n function redeem() public returns (bool) {\n redeemInternal(msg.sender);\n magnifiedFeesCorrections[msg.sender] = magnifiedFeesPerShare.mul(balanceOf(msg.sender));\n return true;\n }\n\n function redeemInternal(address _account) internal {\n uint256 _withdrawableFees = withdrawableFeesOf(_account);\n if (_withdrawableFees > 0) {\n storedFees[_account] = 0;\n collateral.transfer(_account, _withdrawableFees);\n }\n }\n}\n" + }, + "contracts/libraries/Rewardable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nabstract contract Rewardable {\n // Rewards will be paid out over the lifetime of an event.\n // An value of zero will start rewards immediately and proceed based on the values set in master chef.\n\n // _Id here is the market id passed to the amm factory when creating a pool.\n function getRewardEndTime(uint256 _marketId) public view virtual returns (uint256);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "contracts/turbo/OwnedShareToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../libraries/Ownable.sol\";\n\ncontract OwnedERC20 is ERC20, Ownable {\n constructor(\n string memory name_,\n string memory symbol_,\n address _owner\n ) ERC20(name_, symbol_) {\n owner = _owner;\n }\n\n function trustedTransfer(\n address _from,\n address _to,\n uint256 _amount\n ) external onlyOwner {\n _transfer(_from, _to, _amount);\n }\n\n function trustedMint(address _target, uint256 _amount) external onlyOwner {\n _mint(_target, _amount);\n }\n\n function trustedBurn(address _target, uint256 _amount) external onlyOwner {\n _burn(_target, _amount);\n }\n\n function trustedBurnAll(address _target) external onlyOwner returns (uint256) {\n uint256 _balance = balanceOf(_target);\n _burn(_target, _balance);\n return _balance;\n }\n\n function onTransferOwnership(address, address) internal override {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../../utils/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal virtual {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "contracts/libraries/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./IOwnable.sol\";\n\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\nabstract contract Ownable is IOwnable {\n address internal owner;\n\n /**\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n * account.\n */\n constructor() {\n owner = msg.sender;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(msg.sender == owner);\n _;\n }\n\n function getOwner() public view override returns (address) {\n return owner;\n }\n\n /**\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\n * @param _newOwner The address to transfer ownership to.\n */\n function transferOwnership(address _newOwner) public override onlyOwner returns (bool) {\n require(_newOwner != address(0));\n onTransferOwnership(owner, _newOwner);\n owner = _newOwner;\n return true;\n }\n\n // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract\n function onTransferOwnership(address, address) internal virtual;\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n uint256 c = a + b;\n if (c < a) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b > a) return (false, 0);\n return (true, a - b);\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n *\n * _Available since v3.4._\n */\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) return (true, 0);\n uint256 c = a * b;\n if (c / a != b) return (false, 0);\n return (true, c);\n }\n\n /**\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a / b);\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n *\n * _Available since v3.4._\n */\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n if (b == 0) return (false, 0);\n return (true, a % b);\n }\n\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, \"SafeMath: subtraction overflow\");\n return a - b;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a == 0) return 0;\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: division by zero\");\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b > 0, \"SafeMath: modulo by zero\");\n return a % b;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {trySub}.\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n return a - b;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryDiv}.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a / b;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * reverting with custom message when dividing by zero.\n *\n * CAUTION: This function is deprecated because it requires allocating memory for the error\n * message unnecessarily. For custom revert reasons use {tryMod}.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/libraries/IOwnable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\ninterface IOwnable {\n function getOwner() external view returns (address);\n\n function transferOwnership(address _newOwner) external returns (bool);\n}\n" + }, + "contracts/turbo/Fetcher.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"./MMAMarketFactoryV3.sol\";\nimport \"./AMMFactory.sol\";\nimport \"./CryptoMarketFactoryV3.sol\";\nimport \"./NBAMarketFactoryV3.sol\";\nimport \"../rewards/MasterChef.sol\";\nimport \"./CryptoCurrencyMarketFactoryV3.sol\";\n\n// Helper contract for grabbing huge amounts of data without overloading multicall.\nabstract contract Fetcher {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n struct CollateralBundle {\n address addr;\n string symbol;\n uint256 decimals;\n }\n\n struct MarketFactoryBundle {\n uint256 shareFactor;\n uint256 stakerFee;\n uint256 settlementFee;\n uint256 protocolFee;\n FeePot feePot;\n CollateralBundle collateral;\n uint256 marketCount;\n }\n\n struct PoolBundle {\n address addr;\n uint256[] tokenRatios;\n uint256[] balances;\n uint256[] weights;\n uint256 swapFee;\n uint256 totalSupply;\n }\n\n struct StaticMarketBundle {\n AbstractMarketFactoryV3 factory;\n uint256 marketId;\n PoolBundle pool;\n MasterChef.PoolStatusInfo rewards;\n OwnedERC20[] shareTokens;\n uint256 creationTimestamp;\n OwnedERC20 winner;\n uint256[] initialOdds;\n }\n\n struct DynamicMarketBundle {\n AbstractMarketFactoryV3 factory;\n uint256 marketId;\n PoolBundle pool;\n OwnedERC20 winner;\n }\n\n string public marketType;\n string public version;\n\n constructor(string memory _type, string memory _version) {\n marketType = _type;\n version = _version;\n }\n\n function buildCollateralBundle(IERC20Full _collateral) internal view returns (CollateralBundle memory _bundle) {\n _bundle.addr = address(_collateral);\n _bundle.symbol = _collateral.symbol();\n _bundle.decimals = _collateral.decimals();\n }\n\n function buildMarketFactoryBundle(AbstractMarketFactoryV3 _marketFactory)\n internal\n view\n returns (MarketFactoryBundle memory _bundle)\n {\n _bundle.shareFactor = _marketFactory.shareFactor();\n _bundle.stakerFee = _marketFactory.stakerFee();\n _bundle.settlementFee = _marketFactory.settlementFee();\n _bundle.protocolFee = _marketFactory.protocolFee();\n _bundle.feePot = _marketFactory.feePot();\n _bundle.collateral = buildCollateralBundle(_marketFactory.collateral());\n _bundle.marketCount = _marketFactory.marketCount();\n }\n\n function buildStaticMarketBundle(\n AbstractMarketFactoryV3 _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _marketId\n ) internal view returns (StaticMarketBundle memory _bundle) {\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n _bundle.factory = _marketFactory;\n _bundle.marketId = _marketId;\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\n _bundle.rewards = _masterChef.getPoolInfo(_ammFactory, _marketFactory, _marketId);\n _bundle.shareTokens = _market.shareTokens;\n _bundle.creationTimestamp = _market.creationTimestamp;\n _bundle.winner = _market.winner;\n _bundle.initialOdds = _market.initialOdds;\n }\n\n function buildDynamicMarketBundle(\n AbstractMarketFactoryV3 _marketFactory,\n AMMFactory _ammFactory,\n uint256 _marketId\n ) internal view returns (DynamicMarketBundle memory _bundle) {\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n\n _bundle.factory = _marketFactory;\n _bundle.marketId = _marketId;\n _bundle.winner = _market.winner;\n _bundle.pool = buildPoolBundle(_marketFactory, _ammFactory, _marketId);\n }\n\n function buildPoolBundle(\n AbstractMarketFactoryV3 _marketFactory,\n AMMFactory _ammFactory,\n uint256 _marketId\n ) internal view returns (PoolBundle memory _bundle) {\n BPool _pool = _ammFactory.getPool(_marketFactory, _marketId);\n if (_pool == BPool(address(0))) return _bundle;\n\n _bundle.addr = address(_pool);\n _bundle.totalSupply = _pool.totalSupply();\n _bundle.swapFee = _ammFactory.getSwapFee(_marketFactory, _marketId);\n _bundle.balances = _ammFactory.getPoolBalances(_marketFactory, _marketId);\n _bundle.tokenRatios = _ammFactory.tokenRatios(_marketFactory, _marketId);\n _bundle.weights = _ammFactory.getPoolWeights(_marketFactory, _marketId);\n }\n\n function openOrHasWinningShares(AbstractMarketFactoryV3 _marketFactory, uint256 _marketId)\n internal\n view\n returns (bool)\n {\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n if (_market.winner == OwnedERC20(address(0))) return true; // open\n return _market.winner.totalSupply() > 0; // has winning shares\n }\n}\n\nabstract contract SportsFetcher is Fetcher {\n struct SpecificMarketFactoryBundle {\n MarketFactoryBundle super;\n }\n\n struct StaticEventBundle {\n uint256 id;\n StaticMarketBundle[] markets;\n int256[] lines;\n uint256 estimatedStartTime;\n uint256 homeTeamId;\n uint256 awayTeamId;\n string homeTeamName;\n string awayTeamName;\n // Dynamics\n Sport.SportsEventStatus status;\n uint256 homeScore;\n uint256 awayScore;\n }\n\n struct DynamicEventBundle {\n uint256 id;\n Sport.SportsEventStatus status;\n DynamicMarketBundle[] markets;\n uint256 homeScore;\n uint256 awayScore;\n }\n\n function buildSpecificMarketFactoryBundle(address _marketFactory)\n internal\n view\n returns (SpecificMarketFactoryBundle memory _bundle)\n {\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\n }\n\n function fetchInitial(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\n StaticEventBundle[] memory _eventBundles,\n uint256 _lowestEventIndex,\n uint256 _timestamp\n )\n {\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\n (_eventBundles, _lowestEventIndex) = buildStaticEventBundles(\n _marketFactory,\n _ammFactory,\n _masterChef,\n _offset,\n _total\n );\n _timestamp = block.timestamp;\n }\n\n function fetchDynamic(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n DynamicEventBundle[] memory _bundles,\n uint256 _lowestEventIndex,\n uint256 _timestamp\n )\n {\n (_bundles, _lowestEventIndex) = buildDynamicEventBundles(_marketFactory, _ammFactory, _offset, _total);\n _timestamp = block.timestamp;\n }\n\n function buildStaticEventBundles(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n ) internal view returns (StaticEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\n uint256[] memory _eventIds;\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\n\n _total = _eventIds.length;\n _bundles = new StaticEventBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildStaticEventBundle(_marketFactory, _ammFactory, _masterChef, _eventIds[i]);\n }\n }\n\n function buildDynamicEventBundles(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (DynamicEventBundle[] memory _bundles, uint256 _lowestEventIndex) {\n uint256[] memory _eventIds;\n (_eventIds, _lowestEventIndex) = listOfInterestingEvents(_marketFactory, _offset, _total);\n\n _total = _eventIds.length;\n _bundles = new DynamicEventBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildDynamicEventBundle(_marketFactory, _ammFactory, _eventIds[i]);\n }\n }\n\n function buildStaticEventBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _eventId\n ) internal view returns (StaticEventBundle memory _bundle) {\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\n\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_event.markets.length);\n for (uint256 i = 0; i < _markets.length; i++) {\n _markets[i] = buildStaticMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _masterChef,\n _event.markets[i]\n );\n }\n\n _bundle.id = _eventId;\n _bundle.status = _event.status;\n _bundle.markets = _markets;\n _bundle.lines = _event.lines;\n _bundle.estimatedStartTime = _event.estimatedStartTime;\n _bundle.homeTeamId = _event.homeTeamId;\n _bundle.awayTeamId = _event.awayTeamId;\n _bundle.homeTeamName = _event.homeTeamName;\n _bundle.awayTeamName = _event.awayTeamName;\n _bundle.homeScore = _event.homeScore;\n _bundle.awayScore = _event.awayScore;\n }\n\n function buildDynamicEventBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _eventId\n ) internal view returns (DynamicEventBundle memory _bundle) {\n Sport.SportsEvent memory _event = Sport(_marketFactory).getSportsEvent(_eventId);\n\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_event.markets.length);\n for (uint256 i = 0; i < _markets.length; i++) {\n _markets[i] = buildDynamicMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _event.markets[i]\n );\n }\n\n _bundle.id = _eventId;\n _bundle.markets = _markets;\n _bundle.status = _event.status;\n _bundle.homeScore = _event.homeScore;\n _bundle.awayScore = _event.awayScore;\n }\n\n // Starts from the end of the events list because newer events are more interesting.\n // _offset is skipping all events, not just interesting events\n function listOfInterestingEvents(\n address _marketFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (uint256[] memory _interestingEventIds, uint256 _eventIndex) {\n _interestingEventIds = new uint256[](_total);\n\n uint256 _eventCount = Sport(_marketFactory).eventCount();\n\n // No events so return nothing. (needed to avoid integer underflow below)\n if (_eventCount == 0) {\n return (new uint256[](0), 0);\n }\n\n uint256 _max = _eventCount;\n\n // No remaining events so return nothing. (needed to avoid integer underflow below)\n if (_offset > _max) {\n return (new uint256[](0), 0);\n }\n\n uint256 _collectedEvents = 0;\n _eventIndex = _max - _offset;\n while (true) {\n if (_collectedEvents >= _total) break;\n if (_eventIndex == 0) break;\n\n _eventIndex--; // starts out one too high, so this works\n\n (Sport.SportsEvent memory _event, uint256 _eventId) =\n Sport(_marketFactory).getSportsEventByIndex(_eventIndex);\n\n if (isEventInteresting(_event, AbstractMarketFactoryV3(_marketFactory))) {\n _interestingEventIds[_collectedEvents] = _eventId;\n _collectedEvents++;\n }\n }\n\n if (_total > _collectedEvents) {\n assembly {\n // shortens array\n mstore(_interestingEventIds, _collectedEvents)\n }\n }\n }\n\n function isEventInteresting(Sport.SportsEvent memory _event, AbstractMarketFactoryV3 _marketFactory)\n private\n view\n returns (bool)\n {\n for (uint256 i = 0; i < _event.markets.length; i++) {\n uint256 _marketId = _event.markets[i];\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\n return true;\n }\n }\n return false;\n }\n}\n\ncontract NBAFetcher is SportsFetcher {\n constructor() Fetcher(\"NBA\", \"TBD\") {}\n}\n\ncontract MLBFetcher is SportsFetcher {\n constructor() Fetcher(\"MLB\", \"TBD\") {}\n}\n\ncontract MMAFetcher is SportsFetcher {\n constructor() Fetcher(\"MMA\", \"TBD\") {}\n}\n\ncontract NFLFetcher is SportsFetcher {\n constructor() Fetcher(\"NFL\", \"TBD\") {}\n}\n\ncontract CryptoFetcher is Fetcher {\n constructor() Fetcher(\"Crypto\", \"TBD\") {}\n\n struct SpecificMarketFactoryBundle {\n MarketFactoryBundle super;\n }\n\n struct SpecificStaticMarketBundle {\n StaticMarketBundle super;\n uint8 marketType;\n uint256 coinIndex;\n uint256 creationPrice;\n uint256 resolutionTime;\n // Dynamics\n uint256 resolutionPrice;\n }\n\n struct SpecificDynamicMarketBundle {\n DynamicMarketBundle super;\n uint256 resolutionPrice;\n }\n\n function buildSpecificMarketFactoryBundle(address _marketFactory)\n internal\n view\n returns (SpecificMarketFactoryBundle memory _bundle)\n {\n _bundle.super = buildMarketFactoryBundle(CryptoMarketFactoryV3(_marketFactory));\n }\n\n function buildSpecificStaticMarketBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _marketId\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\n CryptoMarketFactoryV3.MarketDetails memory _details =\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\n _bundle.super = buildStaticMarketBundle(\n CryptoMarketFactoryV3(_marketFactory),\n _ammFactory,\n _masterChef,\n _marketId\n );\n _bundle.marketType = uint8(_details.marketType);\n _bundle.creationPrice = _details.creationPrice;\n _bundle.coinIndex = _details.coinIndex;\n _bundle.resolutionPrice = _details.resolutionPrice;\n _bundle.resolutionTime = _details.resolutionTime;\n }\n\n function buildSpecificDynamicMarketBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _marketId\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\n CryptoMarketFactoryV3.MarketDetails memory _details =\n CryptoMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\n _bundle.super = buildDynamicMarketBundle(CryptoMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\n _bundle.resolutionPrice = _details.resolutionPrice;\n }\n\n function fetchInitial(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\n SpecificStaticMarketBundle[] memory _marketBundles,\n uint256 _lowestMarketIndex,\n uint256 _timestamp\n )\n {\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\n\n uint256[] memory _marketIds;\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\n\n _total = _marketIds.length;\n _marketBundles = new SpecificStaticMarketBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _marketBundles[i] = buildSpecificStaticMarketBundle(\n _marketFactory,\n _ammFactory,\n _masterChef,\n _marketIds[i]\n );\n }\n\n _timestamp = block.timestamp;\n }\n\n function fetchDynamic(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificDynamicMarketBundle[] memory _bundles,\n uint256 _lowestMarketIndex,\n uint256 _timestamp\n )\n {\n uint256[] memory _marketIds;\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\n\n _total = _marketIds.length;\n _bundles = new SpecificDynamicMarketBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\n }\n\n _timestamp = block.timestamp;\n }\n\n // Starts from the end of the markets list because newer markets are more interesting.\n // _offset is skipping all markets, not just interesting markets\n function listOfInterestingMarkets(\n address _marketFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\n _interestingMarketIds = new uint256[](_total);\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\n\n // No markets so return nothing. (needed to prevent integer underflow below)\n if (_max == 0 || _offset >= _max) {\n return (new uint256[](0), 0);\n }\n\n // Starts at the end, less offset.\n // Stops before the 0th market since that market is always fake.\n uint256 _collectedMarkets = 0;\n _marketId = _max - _offset;\n\n while (true) {\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\n _interestingMarketIds[_collectedMarkets] = _marketId;\n _collectedMarkets++;\n }\n\n if (_collectedMarkets >= _total) break;\n if (_marketId == 1) break; // skipping 0th market, which is fake\n _marketId--; // starts out oone too high, so this works\n }\n\n if (_total > _collectedMarkets) {\n assembly {\n // shortens array\n mstore(_interestingMarketIds, _collectedMarkets)\n }\n }\n }\n}\n\ncontract CryptoCurrencyFetcher is Fetcher {\n constructor() Fetcher(\"CryptoCurrency\", \"TBD\") {}\n\n struct SpecificMarketFactoryBundle {\n MarketFactoryBundle super;\n }\n\n struct SpecificStaticMarketBundle {\n StaticMarketBundle super;\n uint256 coinIndex;\n uint256 creationValue;\n uint256 resolutionTime;\n // Dynamics\n uint256 resolutionValue;\n }\n\n struct SpecificDynamicMarketBundle {\n DynamicMarketBundle super;\n uint256 resolutionValue;\n }\n\n function buildSpecificMarketFactoryBundle(address _marketFactory)\n internal\n view\n returns (SpecificMarketFactoryBundle memory _bundle)\n {\n _bundle.super = buildMarketFactoryBundle(CryptoCurrencyMarketFactoryV3(_marketFactory));\n }\n\n function buildSpecificStaticMarketBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _marketId\n ) internal view returns (SpecificStaticMarketBundle memory _bundle) {\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\n _bundle.super = buildStaticMarketBundle(\n CryptoCurrencyMarketFactoryV3(_marketFactory),\n _ammFactory,\n _masterChef,\n _marketId\n );\n _bundle.creationValue = _details.creationValue;\n _bundle.coinIndex = _details.coinIndex;\n _bundle.resolutionValue = _details.resolutionValue;\n _bundle.resolutionTime = _details.resolutionTime;\n }\n\n function buildSpecificDynamicMarketBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _marketId\n ) internal view returns (SpecificDynamicMarketBundle memory _bundle) {\n CryptoCurrencyMarketFactoryV3.MarketDetails memory _details =\n CryptoCurrencyMarketFactoryV3(_marketFactory).getMarketDetails(_marketId);\n _bundle.super = buildDynamicMarketBundle(CryptoCurrencyMarketFactoryV3(_marketFactory), _ammFactory, _marketId);\n _bundle.resolutionValue = _details.resolutionValue;\n }\n\n function fetchInitial(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\n SpecificStaticMarketBundle[] memory _marketBundles,\n uint256 _lowestMarketIndex,\n uint256 _timestamp\n )\n {\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\n\n uint256[] memory _marketIds;\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\n\n _total = _marketIds.length;\n _marketBundles = new SpecificStaticMarketBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _marketBundles[i] = buildSpecificStaticMarketBundle(\n _marketFactory,\n _ammFactory,\n _masterChef,\n _marketIds[i]\n );\n }\n\n _timestamp = block.timestamp;\n }\n\n function fetchDynamic(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificDynamicMarketBundle[] memory _bundles,\n uint256 _lowestMarketIndex,\n uint256 _timestamp\n )\n {\n uint256[] memory _marketIds;\n (_marketIds, _lowestMarketIndex) = listOfInterestingMarkets(_marketFactory, _offset, _total);\n\n _total = _marketIds.length;\n _bundles = new SpecificDynamicMarketBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildSpecificDynamicMarketBundle(_marketFactory, _ammFactory, _marketIds[i]);\n }\n\n _timestamp = block.timestamp;\n }\n\n // Starts from the end of the markets list because newer markets are more interesting.\n // _offset is skipping all markets, not just interesting markets\n function listOfInterestingMarkets(\n address _marketFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (uint256[] memory _interestingMarketIds, uint256 _marketId) {\n _interestingMarketIds = new uint256[](_total);\n uint256 _max = AbstractMarketFactoryV3(_marketFactory).marketCount() - 1;\n\n // No markets so return nothing. (needed to prevent integer underflow below)\n if (_max == 0 || _offset >= _max) {\n return (new uint256[](0), 0);\n }\n\n // Starts at the end, less offset.\n // Stops before the 0th market since that market is always fake.\n uint256 _collectedMarkets = 0;\n _marketId = _max - _offset;\n\n while (true) {\n if (openOrHasWinningShares(AbstractMarketFactoryV3(_marketFactory), _marketId)) {\n _interestingMarketIds[_collectedMarkets] = _marketId;\n _collectedMarkets++;\n }\n\n if (_collectedMarkets >= _total) break;\n if (_marketId == 1) break; // skipping 0th market, which is fake\n _marketId--; // starts out oone too high, so this works\n }\n\n if (_total > _collectedMarkets) {\n assembly {\n // shortens array\n mstore(_interestingMarketIds, _collectedMarkets)\n }\n }\n }\n}\n" + }, + "contracts/libraries/SafeMathInt256.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\n/**\n * @title SafeMathInt256\n * @dev Int256 math operations with safety checks that throw on error\n */\nlibrary SafeMathInt256 {\n // Signed ints with n bits can range from -2**(n-1) to (2**(n-1) - 1)\n int256 private constant INT256_MIN = -2**(255);\n int256 private constant INT256_MAX = (2**(255) - 1);\n\n function mul(int256 a, int256 b) internal pure returns (int256) {\n int256 c = a * b;\n require(a == 0 || c / a == b);\n return c;\n }\n\n function div(int256 a, int256 b) internal pure returns (int256) {\n // No need to check for dividing by 0 -- Solidity automatically throws on division by 0\n int256 c = a / b;\n return c;\n }\n\n function sub(int256 a, int256 b) internal pure returns (int256) {\n require(((a >= 0) && (b >= a - INT256_MAX)) || ((a < 0) && (b <= a - INT256_MIN)));\n return a - b;\n }\n\n function add(int256 a, int256 b) internal pure returns (int256) {\n require(((a >= 0) && (b <= INT256_MAX - a)) || ((a < 0) && (b >= INT256_MIN - a)));\n return a + b;\n }\n\n function min(int256 a, int256 b) internal pure returns (int256) {\n if (a <= b) {\n return a;\n } else {\n return b;\n }\n }\n\n function max(int256 a, int256 b) internal pure returns (int256) {\n if (a >= b) {\n return a;\n } else {\n return b;\n }\n }\n\n function abs(int256 a) internal pure returns (int256) {\n if (a < 0) {\n return -a;\n }\n return a;\n }\n\n function getInt256Min() internal pure returns (int256) {\n return INT256_MIN;\n }\n\n function getInt256Max() internal pure returns (int256) {\n return INT256_MAX;\n }\n\n // Float [fixed point] Operations\n function fxpMul(\n int256 a,\n int256 b,\n int256 base\n ) internal pure returns (int256) {\n return div(mul(a, b), base);\n }\n\n function fxpDiv(\n int256 a,\n int256 b,\n int256 base\n ) internal pure returns (int256) {\n return div(mul(a, base), b);\n }\n\n function sqrt(int256 y) internal pure returns (int256 z) {\n if (y > 3) {\n int256 x = (y + 1) / 2;\n z = y;\n while (x < z) {\n z = x;\n x = (y / x + x) / 2;\n }\n } else if (y != 0) {\n z = 1;\n }\n }\n}\n" + }, + "contracts/turbo/MMAMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/Sport.sol\";\nimport \"../libraries/ResolveByFiat.sol\";\nimport \"../libraries/HasHeadToHeadMarket.sol\";\nimport \"../libraries/Versioned.sol\";\n\ncontract MMAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, ResolvesByFiat, HasHeadToHeadMarket, Versioned {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant HeadToHead = 0;\n string constant InvalidName = \"No Contest / Draw\";\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.2.0\")\n ManagedByLink(_linkNode)\n HasHeadToHeadMarket(HeadToHead, InvalidName)\n {}\n\n function createEvent(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\n makeSportsEvent(\n _eventId,\n _marketIds,\n build1Line(),\n _startTimestamp,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName\n );\n }\n\n function makeMarkets(\n int256[2] memory _moneylines,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal returns (uint256[] memory _marketIds) {\n _marketIds = new uint256[](1);\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\n }\n\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal override {\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _whoWon);\n }\n\n function resolveHeadToHeadMarket(uint256 _marketId, uint256 _whoWon) internal {\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_whoWon);\n endMarket(_marketId, _shareTokenIndex);\n }\n\n function calcHeadToHeadWinner(uint256 _whoWon) internal pure returns (uint256) {\n if (WhoWonHome == _whoWon) {\n return HeadToHeadHome;\n } else if (WhoWonAway == _whoWon) {\n return HeadToHeadAway;\n } else {\n return NoContest; // shouldn't happen here\n }\n }\n}\n" + }, + "contracts/turbo/CryptoMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\nimport \"../libraries/Versioned.sol\";\nimport \"../libraries/ManagedByLink.sol\";\nimport \"../libraries/Rewardable.sol\";\n\ncontract CryptoMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event CoinAdded(uint256 indexed id, string name);\n\n event NewPrices(uint256 indexed nextResolutionTime, uint256[] markets, uint256[] prices);\n\n struct Coin {\n string name;\n AggregatorV3Interface priceFeed;\n uint256 price;\n uint8 imprecision; // how many decimals to truncate\n uint256[1] currentMarkets;\n }\n Coin[] public coins;\n\n enum MarketType {\n PriceUpDown // 0\n }\n enum PriceUpDownOutcome {\n Above, // 0\n NotAbove // 1\n }\n struct MarketDetails {\n MarketType marketType;\n uint256 coinIndex;\n uint256 creationPrice;\n uint256 resolutionPrice;\n uint256 resolutionTime; // price at given time; this is that time\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n uint256 public nextResolutionTime;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.2.0\")\n ManagedByLink(_linkNode)\n {\n string memory _name = \"\";\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n // NOTE: Trusts the owner not to add a coin twice.\n // Returns the coin index.\n function addCoin(\n string calldata _name,\n AggregatorV3Interface _priceFeed,\n uint8 _imprecision\n ) external onlyOwner returns (uint256 _coinIndex) {\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\n _coinIndex = coins.length;\n coins.push(_coin);\n emit CoinAdded(_coinIndex, _name);\n }\n\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\n _coin = coins[_coinIndex];\n }\n\n function getCoins() public view returns (Coin[] memory _coins) {\n _coins = new Coin[](coins.length);\n // Skip first coin because it's always the zeroed-out fake coin.\n for (uint256 i = 1; i < coins.length; i++) {\n _coins[i] = coins[i];\n }\n }\n\n // Iterates over all coins.\n // If markets do not exist for coin, create them.\n // Unless _nextResolutionTime is zero; then do not create new markets.\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\n // Else, error.\n //\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\n // coins array.\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public onlyLinkNode {\n // If market creation was stopped then it can be started again.\n // If market creation wasn't stopped then you must wait for market end time to resolve.\n require(block.timestamp >= nextResolutionTime, \"Must wait for market resolution\");\n require(_roundIds.length == coins.length, \"Must specify one roundId for each coin\");\n\n uint256 _resolutionTime = nextResolutionTime;\n nextResolutionTime = _nextResolutionTime;\n\n uint256[] memory _prices = new uint256[](coins.length - 1);\n uint256[] memory _newMarketIds = new uint256[](coins.length - 1);\n // Start at 1 to skip the fake Coin in the 0 index\n for (uint256 i = 1; i < coins.length; i++) {\n (_prices[i - 1], _newMarketIds[i - 1]) = createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\n }\n\n emit NewPrices(nextResolutionTime, _newMarketIds, _prices);\n }\n\n function createAndResolveMarketsForCoin(\n uint256 _coinIndex,\n uint256 _resolutionTime,\n uint80 _roundId\n ) internal returns (uint256 _price, uint256 _newMarketId) {\n Coin memory _coin = coins[_coinIndex];\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\n\n // resolve markets\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\n }\n\n // update price only AFTER resolution\n coins[_coinIndex].price = _newPrice;\n\n // link node sets nextResolutionTime to zero to signify \"do not create markets after resolution\"\n if (nextResolutionTime == 0) {\n return (0, 0);\n }\n\n // create markets\n _newMarketId = createPriceUpDownMarket(_coinIndex, linkNode, _newPrice);\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = _newMarketId;\n\n return (_newPrice, _newMarketId);\n }\n\n function resolvePriceUpDownMarket(\n Coin memory _coin,\n uint256 _newPrice,\n uint256 _fullPrice\n ) internal {\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\n\n uint256 _winningOutcome;\n if (_newPrice > _coin.price) {\n _winningOutcome = uint256(PriceUpDownOutcome.Above);\n } else {\n _winningOutcome = uint256(PriceUpDownOutcome.NotAbove);\n }\n\n endMarket(_marketId, _winningOutcome);\n marketDetails[_marketId].resolutionPrice = _fullPrice;\n }\n\n function createPriceUpDownMarket(\n uint256 _coinIndex,\n address _creator,\n uint256 _newPrice\n ) internal returns (uint256 _id) {\n string[] memory _outcomes = new string[](2);\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \"Above\";\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \"Not Above\";\n\n _id = startMarket(_creator, _outcomes, evenOdds(false, 2), true);\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0, nextResolutionTime);\n }\n\n // Returns the price based on a few factors.\n // If _roundId is zero then it returns the latest price.\n // Else, it returns the price for that round,\n // but errors if that isn't the first round after the resolution time.\n // The price is then altered to match the desired precision.\n function getPrice(\n Coin memory _coin,\n uint80 _roundId,\n uint256 _resolutionTime\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\n if (_roundId == 0) {\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\n require(_rawPrice >= 0, \"Price from feed is negative\");\n _fullPrice = uint256(_rawPrice);\n } else {\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\n require(_rawPrice >= 0, \"Price from feed is negative\");\n require(updatedAt >= _resolutionTime, \"Price hasn't been updated yet\");\n\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\n if (_resolutionTime != 0) {\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\n require(_previousRoundTime < _resolutionTime, \"Must use first round after resolution time\");\n }\n\n _fullPrice = uint256(_rawPrice);\n }\n\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\n\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\n if (_precision > _coin.imprecision) {\n uint8 _truncate = _precision - _coin.imprecision;\n _truncatedPrice = _fullPrice / (10**_truncate);\n } else if (_precision < _coin.imprecision) {\n uint8 _greaten = _coin.imprecision - _precision;\n _truncatedPrice = _fullPrice * (10**_greaten);\n } else {\n _truncatedPrice = _fullPrice;\n }\n\n // Round up because that cleanly fits Above/Not-Above.\n if (_truncatedPrice != _fullPrice) {\n _truncatedPrice += 1;\n }\n }\n\n function makeCoin(\n string memory _name,\n AggregatorV3Interface _priceFeed,\n uint8 _imprecision\n ) internal pure returns (Coin memory _coin) {\n uint256[1] memory _currentMarkets = [uint256(0)];\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\n }\n\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\n // To find the previous roundId:\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\n // 2. decrement the phase-specific round\n // 3. re-encode the phase and phase-specific round.\n uint256 private constant PHASE_OFFSET = 64;\n\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\n uint64 _roundId = uint64(_fullRoundId) - 1;\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\n }\n\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\n return getMarketDetails(_marketId).resolutionTime;\n }\n}\n" + }, + "contracts/turbo/NBAMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/Sport.sol\";\nimport \"../libraries/HasSpreadMarket.sol\";\nimport \"../libraries/ResolveByScore.sol\";\nimport \"../libraries/Versioned.sol\";\n\ncontract NBAMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasSpreadMarket, ResolvesByScore, Versioned {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant Spread = 0;\n string constant InvalidName = \"No Contest\";\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"1.5.0\")\n ManagedByLink(_linkNode)\n HasSpreadMarket(Spread, InvalidName)\n {}\n\n function createEvent(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\n _marketIds = makeMarkets(_homeTeamName, _awayTeamName);\n makeSportsEvent(\n _eventId,\n _marketIds,\n makeLine(_homeSpread),\n _startTimestamp,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName\n );\n }\n\n function makeMarkets(string memory _homeTeamName, string memory _awayTeamName)\n internal\n returns (uint256[] memory _marketIds)\n {\n _marketIds = new uint256[](1);\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\n }\n\n function makeLine(int256 _homeSpread) internal pure returns (int256[] memory _line) {\n _line = build1Line();\n _line[0] = addHalfPoint(_homeSpread);\n }\n\n function resolveValidEvent(\n SportsEvent memory _event,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal override {\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\n }\n}\n" + }, + "contracts/rewards/MasterChef.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\npragma abicoder v2;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/EnumerableSet.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\" as OpenZeppelinOwnable;\nimport \"../turbo/AbstractMarketFactoryV3.sol\";\nimport \"../turbo/AMMFactory.sol\";\n\n// MasterChef is the master of Reward. He can make Reward and he is a fair guy.\ncontract MasterChef is OpenZeppelinOwnable.Ownable {\n using SafeMath for uint256;\n using SafeERC20 for IERC20;\n\n uint256 public constant BONE = 10**18;\n\n // The percentage of the rewards period that early deposit bonus will payout.\n // e.g. Early deposit bonus hits if LP is done in the first x percent of the period.\n uint256 public constant EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE = BONE / 10; // 10% of reward period.\n\n // Info of each user.\n struct UserInfo {\n uint256 amount; // How many LP tokens the user has provided.\n uint256 rewardDebt; // Reward debt. See explanation below.\n uint256 lastActionTimestamp; // Timestamp of the withdrawal or deposit from this user.\n //\n // We do some fancy math here. Basically, any point in time, the amount of REWARDs\n // entitled to a user but is pending to be distributed is:\n //\n // pending reward = (user.amount * pool.accRewardsPerShare) - user.rewardDebt\n //\n // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:\n // 1. The pool's `accRewardsPerShare` (and `lastRewardBlock`) gets updated.\n // 2. User receives the pending reward sent to his/her address.\n // 3. User's `amount` gets updated.\n // 4. User's `rewardDebt` gets updated.\n }\n // Info of each user that deposits LP tokens.\n mapping(uint256 => mapping(address => UserInfo)) public userInfo;\n\n // Info of each pool.\n struct PoolInfo {\n IERC20 lpToken; // Address of LP token contract.\n uint256 accRewardsPerShare; // Accumulated REWARDs per share, times BONE. See below.\n uint256 totalEarlyDepositBonusRewardShares; // The total number of share currently qualifying bonus REWARDs.\n uint256 beginTimestamp; // The timestamp to begin calculating rewards at.\n uint256 endTimestamp; // Timestamp of the end of the rewards period.\n uint256 earlyDepositBonusRewards; // Amount of REWARDs to distribute to early depositors.\n uint256 lastRewardTimestamp; // Last timestamp REWARDs distribution occurred.\n uint256 rewardsPerSecond; // Number of rewards paid out per second.\n }\n // Info of each pool.\n PoolInfo[] public poolInfo;\n\n // This is a snapshot of the current state of a market.\n struct PoolStatusInfo {\n uint256 beginTimestamp;\n uint256 endTimestamp;\n uint256 earlyDepositEndTimestamp;\n uint256 totalRewardsAccrued;\n bool created;\n }\n\n struct PendingRewardInfo {\n uint256 beginTimestamp;\n uint256 endTimestamp;\n uint256 earlyDepositEndTimestamp;\n uint256 accruedStandardRewards;\n uint256 accruedEarlyDepositBonusRewards;\n uint256 pendingEarlyDepositBonusRewards;\n bool created;\n }\n\n struct MarketFactoryInfo {\n uint256 earlyDepositBonusRewards; // Amount of REWARDs per day to distribute to early depositors.\n uint256 rewardsPeriods; // Number of days the rewards for this pool will payout.\n uint256 rewardsPerPeriod; // Amount of rewards to be given out for a given period.\n }\n mapping(address => MarketFactoryInfo) marketFactoryRewardInfo;\n\n struct RewardPoolLookupInfo {\n uint256 pid;\n bool created;\n }\n\n // AMMFactory => MarketFactory => MarketId\n mapping(address => mapping(address => mapping(uint256 => RewardPoolLookupInfo))) public rewardPoolLookup;\n\n // The REWARD TOKEN!\n IERC20 private rewardsToken;\n\n mapping(address => bool) private approvedAMMFactories;\n\n event Deposit(address indexed user, uint256 indexed pid, uint256 amount);\n event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address recipient);\n event TrustMarketFactory(\n address indexed MarketFactory,\n uint256 OriginEarlyDepositBonusRewards,\n uint256 OriginrewardsPeriods,\n uint256 OriginRewardsPerPeriod,\n uint256 EarlyDepositBonusRewards,\n uint256 rewardsPeriods,\n uint256 RewardsPerPeriod\n );\n\n event PoolCreated(\n address indexed ammFactory,\n address indexed marketFactory,\n uint256 indexed marketId,\n address creator,\n address lpTokenRecipient\n );\n event LiquidityChanged(\n address indexed ammFactory,\n address indexed marketFactory,\n uint256 indexed marketId,\n address user,\n address recipient,\n // from the perspective of the user. e.g. collateral is negative when adding liquidity\n int256 collateral,\n int256 lpTokens,\n uint256[] sharesReturned\n );\n\n event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);\n\n constructor(IERC20 _rewardsToken) {\n rewardsToken = _rewardsToken;\n }\n\n function trustAMMFactory(address _ammFactory) public onlyOwner {\n approvedAMMFactories[_ammFactory] = true;\n }\n\n function untrustAMMFactory(address _ammFactory) public onlyOwner {\n delete approvedAMMFactories[_ammFactory];\n }\n\n // This method can also be used to update rewards\n function addRewards(\n address _marketFactory,\n uint256 _rewardsPerMarket,\n uint256 _rewardDaysPerMarket,\n uint256 _earlyDepositBonusRewards\n ) public onlyOwner {\n MarketFactoryInfo memory _oldMarketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\n\n marketFactoryRewardInfo[_marketFactory] = MarketFactoryInfo({\n rewardsPeriods: _rewardDaysPerMarket,\n rewardsPerPeriod: _rewardsPerMarket,\n earlyDepositBonusRewards: _earlyDepositBonusRewards\n });\n\n emit TrustMarketFactory(\n _marketFactory,\n _oldMarketFactoryInfo.earlyDepositBonusRewards,\n _oldMarketFactoryInfo.rewardsPeriods,\n _oldMarketFactoryInfo.rewardsPerPeriod,\n _earlyDepositBonusRewards,\n _rewardDaysPerMarket,\n _rewardsPerMarket\n );\n }\n\n function poolLength() external view returns (uint256) {\n return poolInfo.length;\n }\n\n // Add a new lp to the pool. Can only be called by the owner.\n // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.\n // An _endTimestamp of zero means the rewards start immediately.\n function add(\n address _ammFactory,\n address _marketFactory,\n uint256 _marketId,\n IERC20 _lpToken,\n uint256 _endTimestamp\n ) public onlyOwner returns (uint256 _nextPID) {\n return addInternal(_ammFactory, _marketFactory, _marketId, _lpToken, _endTimestamp);\n }\n\n function addInternal(\n address _ammFactory,\n address _marketFactory,\n uint256 _marketId,\n IERC20 _lpToken,\n uint256 _endTimestamp\n ) internal returns (uint256 _nextPID) {\n require(\n !rewardPoolLookup[_ammFactory][_marketFactory][_marketId].created,\n \"Reward pool has already been created.\"\n );\n\n require(approvedAMMFactories[address(_ammFactory)], \"AMMFactory must be approved to create pool\");\n\n _nextPID = poolInfo.length;\n\n rewardPoolLookup[_ammFactory][_marketFactory][_marketId] = RewardPoolLookupInfo({pid: _nextPID, created: true});\n\n MarketFactoryInfo memory _marketFactoryInfo = marketFactoryRewardInfo[_marketFactory];\n\n // Need to figure out the beginning/end of the reward period.\n uint256 _rewardsPeriodsInSeconds = _marketFactoryInfo.rewardsPeriods * 1 days;\n uint256 _beginTimestamp = block.timestamp;\n\n // Add one hour buffer for LPs to withdraw before event start.\n if (_endTimestamp != 0) {\n _endTimestamp = _endTimestamp - 1 hours;\n }\n\n if (_endTimestamp == 0) {\n _endTimestamp = _beginTimestamp + _rewardsPeriodsInSeconds;\n } else if ((_endTimestamp - _rewardsPeriodsInSeconds) > block.timestamp) {\n _beginTimestamp = _endTimestamp - _rewardsPeriodsInSeconds;\n } else if (block.timestamp >= _endTimestamp) {\n // reward period already over.\n _beginTimestamp = _endTimestamp;\n }\n poolInfo.push(\n PoolInfo({\n accRewardsPerShare: 0,\n beginTimestamp: _beginTimestamp,\n endTimestamp: _endTimestamp,\n totalEarlyDepositBonusRewardShares: 0,\n earlyDepositBonusRewards: (_marketFactoryInfo.earlyDepositBonusRewards / 1 days) *\n (_endTimestamp - _beginTimestamp),\n lpToken: _lpToken,\n rewardsPerSecond: (_marketFactoryInfo.rewardsPerPeriod / 1 days),\n lastRewardTimestamp: _beginTimestamp\n })\n );\n }\n\n // Return number of seconds elapsed in terms of BONEs.\n function getTimeElapsed(uint256 _pid) public view returns (uint256) {\n PoolInfo storage _pool = poolInfo[_pid];\n uint256 _fromTimestamp = block.timestamp;\n\n if (\n // Rewards have not started yet.\n _pool.beginTimestamp > _fromTimestamp ||\n // Not sure how this happens but it is accounted for in the original master chef contract.\n _pool.lastRewardTimestamp > _fromTimestamp ||\n // No rewards to be distributed\n _pool.rewardsPerSecond == 0\n ) {\n return 0;\n }\n\n // Rewards are over for this pool. No more rewards have accrued.\n if (_pool.lastRewardTimestamp >= _pool.endTimestamp) {\n return 0;\n }\n\n return min(_fromTimestamp, _pool.endTimestamp).sub(_pool.lastRewardTimestamp).add(1).mul(BONE);\n }\n\n function getPoolTokenBalance(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n address _user\n ) external view returns (uint256) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n if (_rewardPoolLookupInfo.created) {\n return userInfo[_rewardPoolLookupInfo.pid][_user].amount;\n } else {\n return 0;\n }\n }\n\n function getUserAmount(uint256 _pid, address _user) external view returns (uint256) {\n return userInfo[_pid][_user].amount;\n }\n\n function getPoolRewardEndTimestamp(uint256 _pid) public view returns (uint256) {\n PoolInfo storage _pool = poolInfo[_pid];\n return _pool.endTimestamp;\n }\n\n function getEarlyDepositEndTimestamp(uint256 _pid) public view returns (uint256) {\n PoolInfo storage _pool = poolInfo[_pid];\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\n\n return ((_duration * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\n }\n\n function getPoolLPTokenTotalSupply(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId\n ) public view returns (uint256) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken.totalSupply();\n }\n\n function getPoolLPToken(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId\n ) public view returns (IERC20) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n return poolInfo[_rewardPoolLookupInfo.pid].lpToken;\n }\n\n function getPoolInfo(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId\n ) public view returns (PoolStatusInfo memory _poolStatusInfo) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n // This cannot revert as it will be used in a multicall.\n if (_rewardPoolLookupInfo.created) {\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\n\n _poolStatusInfo.beginTimestamp = _pool.beginTimestamp;\n _poolStatusInfo.endTimestamp = _pool.endTimestamp;\n _poolStatusInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\n\n _poolStatusInfo.totalRewardsAccrued =\n (min(block.timestamp, _pool.endTimestamp) - _pool.beginTimestamp) *\n _pool.rewardsPerSecond;\n _poolStatusInfo.created = true;\n }\n }\n\n // View function to see pending REWARDs on frontend.\n function getUserPendingRewardInfo(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n address _userAddress\n ) external view returns (PendingRewardInfo memory _pendingRewardInfo) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n if (_rewardPoolLookupInfo.created) {\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\n UserInfo storage _user = userInfo[_rewardPoolLookupInfo.pid][_userAddress];\n uint256 accRewardsPerShare = _pool.accRewardsPerShare;\n uint256 lpSupply = _pool.lpToken.balanceOf(address(this));\n\n uint256 _duration = _pool.endTimestamp - _pool.beginTimestamp;\n\n _pendingRewardInfo.created = true;\n _pendingRewardInfo.beginTimestamp = _pool.beginTimestamp;\n _pendingRewardInfo.endTimestamp = _pool.endTimestamp;\n _pendingRewardInfo.earlyDepositEndTimestamp = getEarlyDepositEndTimestamp(_rewardPoolLookupInfo.pid);\n\n if (_user.lastActionTimestamp <= _pendingRewardInfo.earlyDepositEndTimestamp) {\n if (_pool.totalEarlyDepositBonusRewardShares > 0 && block.timestamp > _pendingRewardInfo.endTimestamp) {\n _pendingRewardInfo.accruedEarlyDepositBonusRewards = _pool\n .earlyDepositBonusRewards\n .mul(_user.amount)\n .div(_pool.totalEarlyDepositBonusRewardShares);\n } else if (_pool.totalEarlyDepositBonusRewardShares > 0) {\n _pendingRewardInfo.pendingEarlyDepositBonusRewards = _pool\n .earlyDepositBonusRewards\n .mul(_user.amount)\n .div(_pool.totalEarlyDepositBonusRewardShares);\n }\n }\n\n if (block.timestamp > _pool.lastRewardTimestamp && lpSupply != 0) {\n uint256 multiplier = getTimeElapsed(_rewardPoolLookupInfo.pid);\n accRewardsPerShare = accRewardsPerShare.add(multiplier.mul(_pool.rewardsPerSecond).div(lpSupply));\n }\n\n _pendingRewardInfo.accruedStandardRewards = _user.amount.mul(accRewardsPerShare).div(BONE).sub(\n _user.rewardDebt\n );\n }\n }\n\n // Update reward variables for all pools. Be careful of gas spending!\n function massUpdatePools() public {\n uint256 length = poolInfo.length;\n for (uint256 pid = 0; pid < length; ++pid) {\n updatePool(pid);\n }\n }\n\n // Update reward variables of the given pool to be up-to-date.\n function updatePool(uint256 _pid) public {\n PoolInfo storage pool = poolInfo[_pid];\n if (block.timestamp <= pool.lastRewardTimestamp) {\n return;\n }\n uint256 lpSupply = pool.lpToken.balanceOf(address(this));\n if (lpSupply == 0) {\n pool.lastRewardTimestamp = block.timestamp;\n return;\n }\n uint256 multiplier = getTimeElapsed(_pid);\n pool.accRewardsPerShare = pool.accRewardsPerShare.add(multiplier.mul(pool.rewardsPerSecond).div(lpSupply));\n pool.lastRewardTimestamp = block.timestamp;\n }\n\n // Deposit LP tokens to MasterChef for REWARD allocation.\n // Assumes the staked tokens are already on contract.\n function depositInternal(\n address _userAddress,\n uint256 _pid,\n uint256 _amount\n ) internal {\n PoolInfo storage _pool = poolInfo[_pid];\n UserInfo storage _user = userInfo[_pid][_userAddress];\n\n updatePool(_pid);\n\n if (_user.amount > 0) {\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\n safeRewardsTransfer(_userAddress, pending);\n }\n\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\n uint256 _bonusrewardsPeriodsEndTimestamp =\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\n\n // If the user was an early deposit, remove user amount from the pool.\n // Even if the pools reward period has elapsed. They must withdraw first.\n if (\n block.timestamp > _bonusrewardsPeriodsEndTimestamp &&\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\n ) {\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\n }\n\n // Still in the early deposit bonus period.\n if (_bonusrewardsPeriodsEndTimestamp > block.timestamp) {\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.add(_amount);\n }\n\n _user.amount = _user.amount.add(_amount);\n\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\n _user.lastActionTimestamp = block.timestamp;\n emit Deposit(_userAddress, _pid, _amount);\n }\n\n function depositByMarket(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _amount\n ) public {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n require(_rewardPoolLookupInfo.created, \"Reward pool has not been created.\");\n\n deposit(_rewardPoolLookupInfo.pid, _amount);\n }\n\n function deposit(uint256 _pid, uint256 _amount) public {\n depositInternal(msg.sender, _pid, _amount);\n poolInfo[_pid].lpToken.safeTransferFrom(msg.sender, address(this), _amount);\n }\n\n // Withdraw LP tokens from MasterChef.\n // Assumes caller is handling distribution of LP tokens.\n function withdrawInternal(\n address _userAddress,\n uint256 _pid,\n uint256 _amount,\n address _tokenRecipientAddress\n ) internal {\n PoolInfo storage _pool = poolInfo[_pid];\n UserInfo storage _user = userInfo[_pid][_userAddress];\n require(_user.amount >= _amount, \"withdraw: not good\");\n\n updatePool(_pid);\n\n uint256 _rewardsPeriodsInSeconds = _pool.endTimestamp - _pool.beginTimestamp;\n uint256 _bonusrewardsPeriodsEndTimestamp =\n ((_rewardsPeriodsInSeconds * EARLY_DEPOSIT_BONUS_REWARDS_PERCENTAGE) / BONE) + _pool.beginTimestamp + 1;\n uint256 _rewardPeriodEndTimestamp = _rewardsPeriodsInSeconds + _pool.beginTimestamp + 1;\n\n if (_rewardPeriodEndTimestamp <= block.timestamp) {\n if (\n _pool.totalEarlyDepositBonusRewardShares > 0 &&\n _user.lastActionTimestamp <= _bonusrewardsPeriodsEndTimestamp\n ) {\n uint256 _rewardsToUser =\n _pool.earlyDepositBonusRewards.mul(_user.amount).div(_pool.totalEarlyDepositBonusRewardShares);\n safeRewardsTransfer(_userAddress, _rewardsToUser);\n }\n } else if (_bonusrewardsPeriodsEndTimestamp >= block.timestamp) {\n // Still in the early deposit bonus period.\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_amount);\n } else if (\n // If the user was an early deposit, remove user amount from the pool.\n _bonusrewardsPeriodsEndTimestamp >= _user.lastActionTimestamp\n ) {\n _pool.totalEarlyDepositBonusRewardShares = _pool.totalEarlyDepositBonusRewardShares.sub(_user.amount);\n }\n\n uint256 pending = _user.amount.mul(_pool.accRewardsPerShare).div(BONE).sub(_user.rewardDebt);\n\n safeRewardsTransfer(_tokenRecipientAddress, pending);\n _user.amount = _user.amount.sub(_amount);\n _user.rewardDebt = _user.amount.mul(_pool.accRewardsPerShare).div(BONE);\n _user.lastActionTimestamp = block.timestamp;\n\n emit Withdraw(msg.sender, _pid, _amount, _tokenRecipientAddress);\n }\n\n function withdrawByMarket(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _amount\n ) public {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n require(_rewardPoolLookupInfo.created, \"Reward pool has not been created.\");\n\n withdraw(_rewardPoolLookupInfo.pid, _amount);\n }\n\n function withdraw(uint256 _pid, uint256 _amount) public {\n withdrawInternal(msg.sender, _pid, _amount, msg.sender);\n poolInfo[_pid].lpToken.safeTransfer(msg.sender, _amount);\n }\n\n function createPool(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _initialLiquidity,\n address _lpTokenRecipient\n ) public returns (uint256) {\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _initialLiquidity);\n _marketFactory.collateral().approve(address(_ammFactory), _initialLiquidity);\n\n uint256 _lpTokensIn = _ammFactory.createPool(_marketFactory, _marketId, _initialLiquidity, address(this));\n IERC20 _lpToken = IERC20(address(_ammFactory.getPool(_marketFactory, _marketId)));\n\n uint256 _nextPID =\n addInternal(\n address(_ammFactory),\n address(_marketFactory),\n _marketId,\n _lpToken,\n _marketFactory.getRewardEndTime(_marketId)\n );\n\n depositInternal(_lpTokenRecipient, _nextPID, _lpTokensIn);\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n uint256[] memory _balances = new uint256[](_market.shareTokens.length);\n for (uint256 i = 0; i < _market.shareTokens.length; i++) {\n _balances[i] = 0;\n }\n\n emit PoolCreated(address(_ammFactory), address(_marketFactory), _marketId, msg.sender, _lpTokenRecipient);\n emit LiquidityChanged(\n address(_ammFactory),\n address(_marketFactory),\n _marketId,\n msg.sender,\n _lpTokenRecipient,\n -int256(_initialLiquidity),\n int256(_lpTokensIn),\n _balances\n );\n\n return _lpTokensIn;\n }\n\n function addLiquidity(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _collateralIn,\n uint256 _minLPTokensOut,\n address _lpTokenRecipient\n ) public returns (uint256 _poolAmountOut, uint256[] memory _balances) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n uint256 _pid = _rewardPoolLookupInfo.pid;\n\n // If not created should attempt to create it.\n if (!_rewardPoolLookupInfo.created) {\n BPool _bPool = _ammFactory.getPool(_marketFactory, _marketId);\n require(_bPool != BPool(0), \"Pool not created.\");\n\n _pid = addInternal(\n address(_ammFactory),\n address(_marketFactory),\n _marketId,\n IERC20(address(_bPool)),\n _marketFactory.getRewardEndTime(_marketId)\n );\n }\n\n _marketFactory.collateral().transferFrom(msg.sender, address(this), _collateralIn);\n _marketFactory.collateral().approve(address(_ammFactory), _collateralIn);\n\n (_poolAmountOut, _balances) = _ammFactory.addLiquidity(\n _marketFactory,\n _marketId,\n _collateralIn,\n _minLPTokensOut,\n address(this)\n );\n\n AbstractMarketFactoryV3.Market memory _market = _marketFactory.getMarket(_marketId);\n for (uint256 i = 0; i < _balances.length; i++) {\n if (_balances[i] > 0) {\n _market.shareTokens[i].transfer(_lpTokenRecipient, _balances[i]);\n }\n }\n\n depositInternal(_lpTokenRecipient, _pid, _poolAmountOut);\n\n emit LiquidityChanged(\n address(_ammFactory),\n address(_marketFactory),\n _marketId,\n msg.sender,\n _lpTokenRecipient,\n -int256(_collateralIn),\n int256(_poolAmountOut),\n _balances\n );\n }\n\n function removeLiquidity(\n AMMFactory _ammFactory,\n AbstractMarketFactoryV3 _marketFactory,\n uint256 _marketId,\n uint256 _lpTokensIn,\n uint256 _minCollateralOut,\n address _collateralRecipient\n ) public returns (uint256 _collateralOut, uint256[] memory _balances) {\n RewardPoolLookupInfo memory _rewardPoolLookupInfo =\n rewardPoolLookup[address(_ammFactory)][address(_marketFactory)][_marketId];\n\n require(_rewardPoolLookupInfo.created, \"Reward pool has not been created.\");\n\n withdrawInternal(msg.sender, _rewardPoolLookupInfo.pid, _lpTokensIn, _collateralRecipient);\n\n PoolInfo storage _pool = poolInfo[_rewardPoolLookupInfo.pid];\n\n _pool.lpToken.approve(address(_ammFactory), _lpTokensIn);\n\n (_collateralOut, _balances) = _ammFactory.removeLiquidity(\n _marketFactory,\n _marketId,\n _lpTokensIn,\n _minCollateralOut,\n _collateralRecipient\n );\n\n emit LiquidityChanged(\n address(_ammFactory),\n address(_marketFactory),\n _marketId,\n msg.sender,\n _collateralRecipient,\n int256(_collateralOut),\n -int256(_lpTokensIn),\n _balances\n );\n }\n\n function withdrawRewards(uint256 _amount) external onlyOwner {\n rewardsToken.transfer(msg.sender, _amount);\n }\n\n // Withdraw without caring about rewards. EMERGENCY ONLY.\n function emergencyWithdraw(uint256 _pid) public {\n PoolInfo storage pool = poolInfo[_pid];\n UserInfo storage user = userInfo[_pid][msg.sender];\n pool.lpToken.safeTransfer(address(msg.sender), user.amount);\n emit EmergencyWithdraw(msg.sender, _pid, user.amount);\n user.amount = 0;\n user.rewardDebt = 0;\n user.lastActionTimestamp = 0;\n }\n\n function safeRewardsTransfer(address _to, uint256 _amount) internal {\n uint256 _rewardsBal = rewardsToken.balanceOf(address(this));\n if (_amount > _rewardsBal) {\n rewardsToken.transfer(_to, _rewardsBal);\n } else {\n rewardsToken.transfer(_to, _amount);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n if (a <= b) {\n return a;\n } else {\n return b;\n }\n }\n}\n" + }, + "contracts/turbo/CryptoCurrencyMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\nimport \"../libraries/Versioned.sol\";\nimport \"../libraries/ManagedByLink.sol\";\n\ncontract CryptoCurrencyMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned, ManagedByLink {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event CoinAdded(uint256 indexed id, string name);\n event ValueUpdate(uint256 indexed coinIndex, uint256 indexed resolutionTime, uint256 market, uint256 value);\n\n enum Outcome {\n Above, // 0\n NotAbove // 1\n }\n string constant Above = \"Above\";\n string constant NotAbove = \"Not Above\";\n\n struct Coin {\n string name;\n AggregatorV3Interface feed;\n uint256 value;\n uint8 imprecision; // how many decimals to truncate\n uint256 currentMarket; // 0 indicates no current market\n }\n Coin[] public coins;\n\n struct MarketDetails {\n uint256 coinIndex;\n uint256 creationValue;\n uint256 resolutionValue;\n uint256 resolutionTime; // value at given time; this is that time\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.3.3\")\n ManagedByLink(_linkNode)\n {\n string memory _name = \"\";\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n // NOTE: Trusts the owner not to add a coin twice.\n function addCoin(\n string calldata _name,\n AggregatorV3Interface _feed,\n uint8 _imprecision\n ) external onlyOwner returns (uint256 _coinIndex) {\n Coin memory _coin = makeCoin(_name, _feed, _imprecision);\n _coinIndex = coins.length;\n coins.push(_coin);\n emit CoinAdded(_coinIndex, _name);\n }\n\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\n _coin = coins[_coinIndex];\n }\n\n function getCoins() public view returns (Coin[] memory _coins) {\n _coins = new Coin[](coins.length);\n // Skip first coin because it's always the zeroed-out fake coin.\n for (uint256 i = 1; i < coins.length; i++) {\n _coins[i] = coins[i];\n }\n }\n\n // If _resolutionTime is 0 then do NOT create.\n // If _roundId is 0 then do NOT resolve.\n function pokeCoin(\n uint256 _coinIndex,\n uint256 _resolutionTime,\n uint80 _roundId\n ) public onlyLinkNode {\n Coin storage _coin = coins[_coinIndex];\n\n // There's a market to resolve.\n if (_roundId != 0 && _coin.currentMarket != 0) {\n resolveMarket(_coin, _roundId);\n }\n\n // Create a market\n if (_resolutionTime != 0 && _coin.currentMarket == 0) {\n createMarket(_coinIndex, _coin, _resolutionTime);\n }\n }\n\n function createMarket(\n uint256 _coinIndex,\n Coin storage _coin,\n uint256 _resolutionTime\n ) internal returns (uint256 _marketId) {\n (, uint256 _newValue) = getLatestValue(_coin);\n\n string[] memory _outcomes = new string[](2);\n _outcomes[uint256(Outcome.Above)] = Above;\n _outcomes[uint256(Outcome.NotAbove)] = NotAbove;\n\n _marketId = startMarket(linkNode, _outcomes, evenOdds(false, 2), true);\n marketDetails[_marketId] = MarketDetails(_coinIndex, _newValue, 0, _resolutionTime);\n _coin.currentMarket = _marketId;\n _coin.value = _newValue;\n emit ValueUpdate(_coinIndex, _resolutionTime, _marketId, _newValue);\n }\n\n function resolveMarket(Coin storage _coin, uint80 _roundId) internal {\n uint256 _resolutionTime = marketDetails[_coin.currentMarket].resolutionTime;\n (uint256 _fullValue, uint256 _newValue) = getSpecificValue(_coin, _roundId, _resolutionTime);\n\n uint256 _winningOutcome;\n if (_newValue > _coin.value) {\n _winningOutcome = uint256(Outcome.Above);\n } else {\n _winningOutcome = uint256(Outcome.NotAbove);\n }\n\n endMarket(_coin.currentMarket, _winningOutcome);\n marketDetails[_coin.currentMarket].resolutionValue = _fullValue;\n _coin.currentMarket = 0;\n _coin.value = 0;\n }\n\n function getLatestValue(Coin storage _coin) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\n (, int256 _rawValue, , , ) = _coin.feed.latestRoundData();\n require(_rawValue >= 0, \"Value from feed is negative\");\n _fullValue = uint256(_rawValue);\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\n }\n\n // Get value at a specific round, but fail if it isn't after a specific time.\n function getSpecificValue(\n Coin storage _coin,\n uint80 _roundId,\n uint256 _resolutionTime\n ) internal view returns (uint256 _fullValue, uint256 _truncatedValue) {\n (, int256 _rawValue, , uint256 _updatedAt, ) = _coin.feed.getRoundData(_roundId);\n require(_rawValue >= 0, \"Value from feed is negative\");\n require(_updatedAt >= _resolutionTime, \"Value hasn't been updated yet\");\n\n (, , , uint256 _previousRoundTime, ) = _coin.feed.getRoundData(previousRound(_roundId));\n require(_previousRoundTime < _resolutionTime, \"Must use first round after resolution time\");\n\n _fullValue = uint256(_rawValue);\n _truncatedValue = calcTruncatedValue(_coin, _fullValue);\n }\n\n // The precision is how many decimals the value has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\n function calcTruncatedValue(Coin storage _coin, uint256 _fullValue)\n internal\n view\n returns (uint256 _truncatedValue)\n {\n uint8 _precision = _coin.feed.decimals(); // probably constant but that isn't guaranteed, so query each time\n if (_precision > _coin.imprecision) {\n uint8 _truncate = _precision - _coin.imprecision;\n _truncatedValue = _fullValue / (10**_truncate);\n } else if (_precision < _coin.imprecision) {\n uint8 _greaten = _coin.imprecision - _precision;\n _truncatedValue = _fullValue * (10**_greaten);\n } else {\n _truncatedValue = _fullValue;\n }\n\n // Round up because that cleanly fits Above/Not-Above.\n if (_truncatedValue != _fullValue) {\n _truncatedValue += 1;\n }\n }\n\n function makeCoin(\n string memory _name,\n AggregatorV3Interface _feed,\n uint8 _imprecision\n ) internal pure returns (Coin memory _coin) {\n _coin = Coin(_name, _feed, 0, _imprecision, 0);\n }\n\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\n // To find the previous roundId:\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\n // 2. decrement the phase-specific round\n // 3. re-encode the phase and phase-specific round.\n uint256 private constant PHASE_OFFSET = 64;\n\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\n uint64 _roundId = uint64(_fullRoundId) - 1;\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\n }\n\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\n return getMarketDetails(_marketId).resolutionTime;\n }\n}\n" + }, + "contracts/libraries/Sport.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../turbo/AbstractMarketFactoryV3.sol\";\nimport \"./LineHelper.sol\";\n\nabstract contract Sport is AbstractMarketFactoryV3, LineHelper {\n event SportsEventCreated(\n uint256 id,\n uint256[] markets,\n int256[] lines,\n uint256 homeTeamId,\n uint256 awayTeamId,\n string homeTeamName,\n string awayTeamName,\n uint256 estimatedStartTime\n );\n\n enum SportsEventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\n struct SportsEvent {\n SportsEventStatus status;\n uint256[] markets;\n int256[] lines;\n uint256 estimatedStartTime;\n uint256 homeTeamId;\n uint256 awayTeamId;\n string homeTeamName;\n string awayTeamName;\n uint256 homeScore;\n uint256 awayScore;\n }\n // EventId => EventDetails\n mapping(uint256 => SportsEvent) public sportsEvents;\n uint256[] public listOfSportsEvents;\n mapping(uint256 => uint256) public marketIdToEventIdMapping;\n uint256 constant NoContest = 0;\n\n function eventCount() public view returns (uint256) {\n return listOfSportsEvents.length;\n }\n\n function getSportsEvent(uint256 _eventId) public view returns (SportsEvent memory) {\n return sportsEvents[_eventId];\n }\n\n function getSportsEventByIndex(uint256 _index) public view returns (SportsEvent memory _event, uint256 _eventId) {\n _eventId = listOfSportsEvents[_index];\n _event = getSportsEvent(_eventId);\n }\n\n function makeSportsEvent(\n uint256 _eventId,\n uint256[] memory _markets,\n int256[] memory _lines,\n uint256 _estimatedStartTime,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal {\n // Cannot create markets for an event twice.\n require(sportsEvents[_eventId].status == SportsEventStatus.Unknown, \"event exists\");\n\n for (uint256 i = 0; i < _markets.length; i++) {\n marketIdToEventIdMapping[_markets[i]] = _eventId;\n }\n\n listOfSportsEvents.push(_eventId);\n sportsEvents[_eventId].status = SportsEventStatus.Scheduled; // new events must be Scheduled\n sportsEvents[_eventId].markets = _markets;\n sportsEvents[_eventId].lines = _lines;\n sportsEvents[_eventId].estimatedStartTime = _estimatedStartTime;\n sportsEvents[_eventId].homeTeamId = _homeTeamId;\n sportsEvents[_eventId].awayTeamId = _awayTeamId;\n sportsEvents[_eventId].homeTeamName = _homeTeamName;\n sportsEvents[_eventId].awayTeamName = _awayTeamName;\n // homeScore and awayScore default to zero, which is correct for new events\n\n emit SportsEventCreated(\n _eventId,\n _markets,\n _lines,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName,\n _estimatedStartTime\n );\n }\n\n uint256 constant WhoWonUnknown = 0;\n uint256 constant WhoWonHome = 1;\n uint256 constant WhoWonAway = 2;\n uint256 constant WhoWonDraw = 3;\n\n function eventIsNoContest(\n SportsEvent memory _event,\n SportsEventStatus _eventStatus,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _whoWon // pass in WhoWonUnknown if using a scoring sport\n ) internal pure returns (bool) {\n bool _draw = _whoWon == WhoWonDraw;\n bool _notFinal = _eventStatus != SportsEventStatus.Final;\n bool _unstableHomeTeamId = _event.homeTeamId != _homeTeamId;\n bool _unstableAwayTeamId = _event.awayTeamId != _awayTeamId;\n return _draw || _notFinal || _unstableHomeTeamId || _unstableAwayTeamId;\n }\n\n function resolveInvalidEvent(uint256 _eventId) internal {\n uint256[] memory _marketIds = sportsEvents[_eventId].markets;\n for (uint256 i = 0; i < _marketIds.length; i++) {\n uint256 _marketId = _marketIds[i];\n if (_marketId == 0) continue; // skip non-created markets\n endMarket(_marketId, NoContest);\n }\n }\n\n // TODO is this needed? getSportsEvent should do the same\n function getEventMarkets(uint256 _eventId) public view returns (uint256[] memory _markets) {\n uint256[] storage _original = sportsEvents[_eventId].markets;\n uint256 _len = _original.length;\n _markets = new uint256[](_len);\n for (uint256 i = 0; i < _len; i++) {\n _markets[i] = _original[i];\n }\n }\n\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\n uint256 _eventId = marketIdToEventIdMapping[_marketId];\n return getSportsEvent(_eventId).estimatedStartTime;\n }\n}\n\n// TODO change this to work with the Fetcher contracts and use it there, since it's offchain-read-only.\nabstract contract SportView is Sport {\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n // Lists all events that could be resolved with a call to resolveEvent.\n // Not all will be resolvable because this does not ensure the game ended.\n function listResolvableEvents() external view returns (uint256[] memory) {\n uint256 _totalResolvable = countResolvableEvents();\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\n\n uint256 n = 0;\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\n if (n > _totalResolvable) break;\n uint256 _eventId = listOfSportsEvents[i];\n if (isEventResolvable(_eventId)) {\n _resolvableEvents[n] = _eventId;\n n++;\n }\n }\n\n return _resolvableEvents;\n }\n\n function countResolvableEvents() internal view returns (uint256) {\n uint256 _totalResolvable = 0;\n for (uint256 i = 0; i < listOfSportsEvents.length; i++) {\n uint256 _eventId = listOfSportsEvents[i];\n if (isEventResolvable(_eventId)) {\n _totalResolvable++;\n }\n }\n return _totalResolvable;\n }\n\n // Returns true if a call to resolveEvent is potentially useful.\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\n uint256[] memory _markets = getEventMarkets(_eventId);\n\n bool _unresolved = false; // default because non-existing markets aren't resolvable\n for (uint256 i = 0; i < _markets.length; i++) {\n uint256 _marketId = _markets[i];\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\n _unresolved = true;\n break;\n }\n }\n\n return _unresolved;\n }\n}\n" + }, + "contracts/libraries/ResolveByFiat.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./Sport.sol\";\nimport \"./ManagedByLink.sol\";\n\nabstract contract ResolvesByFiat is Sport, ManagedByLink {\n function resolveEvent(\n uint256 _eventId,\n SportsEventStatus _eventStatus,\n uint256 _homeTeamId, // for verifying team stability\n uint256 _awayTeamId, // for verifying team stability\n uint256 _whoWon\n ) public onlyLinkNode {\n SportsEvent storage _event = sportsEvents[_eventId];\n\n require(_event.status == SportsEventStatus.Scheduled);\n require(SportsEventStatus(_eventStatus) != SportsEventStatus.Scheduled);\n\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, _whoWon)) {\n resolveInvalidEvent(_eventId);\n } else {\n resolveValidEvent(_event, _whoWon);\n }\n\n sportsEvents[_eventId].status = _eventStatus;\n }\n\n function resolveValidEvent(SportsEvent memory _event, uint256 _whoWon) internal virtual;\n}\n" + }, + "contracts/libraries/HasHeadToHeadMarket.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../turbo/AbstractMarketFactoryV3.sol\";\nimport \"./Sport.sol\";\nimport \"./CalculateLinesToBPoolOdds.sol\";\nimport \"./TokenNamesFromTeams.sol\";\n\nabstract contract HasHeadToHeadMarket is\n AbstractMarketFactoryV3,\n Sport,\n CalculateLinesToBPoolOdds,\n TokenNamesFromTeams\n{\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 private headToHeadMarketType;\n string private noContestName;\n\n uint256 constant HeadToHeadAway = 1;\n uint256 constant HeadToHeadHome = 2;\n\n constructor(uint256 _marketType, string memory _noContestName) {\n headToHeadMarketType = _marketType;\n noContestName = _noContestName;\n }\n\n function makeHeadToHeadMarket(\n int256[2] memory _moneylines,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal returns (uint256) {\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\n return\n makeSportsMarket(\n noContestName,\n _homeTeamName,\n _awayTeamName,\n oddsFromLines(_moneylines[1], _moneylines[0])\n );\n }\n\n function resolveHeadToHeadMarket(\n uint256 _marketId,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n uint256 _shareTokenIndex = calcHeadToHeadWinner(_homeScore, _awayScore);\n endMarket(_marketId, _shareTokenIndex);\n }\n\n function calcHeadToHeadWinner(uint256 _homeScore, uint256 _awayScore) private pure returns (uint256) {\n if (_homeScore > _awayScore) {\n return HeadToHeadHome;\n } else if (_homeScore < _awayScore) {\n return HeadToHeadAway;\n } else {\n return NoContest;\n }\n }\n}\n" + }, + "contracts/libraries/Versioned.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nabstract contract Versioned {\n string internal version;\n\n constructor(string memory _version) {\n version = _version;\n }\n\n function getVersion() public view returns (string memory) {\n return version;\n }\n}\n" + }, + "contracts/libraries/LineHelper.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nabstract contract LineHelper {\n function build1Line() internal pure returns (int256[] memory _lines) {\n _lines = new int256[](1);\n }\n\n function build3Lines(int256 _homeSpread, int256 _totalScore) internal pure returns (int256[] memory _lines) {\n _lines = new int256[](3);\n // 0 is the Head-to-Head market, which has no lines\n _lines[1] = addHalfPoint(_homeSpread);\n _lines[2] = addHalfPoint(_totalScore);\n }\n\n function addHalfPoint(int256 _line) internal pure returns (int256) {\n // The line is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the line is a whole number then make it a half point more extreme, to eliminate ties.\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\n if (_line >= 0 && _line % 10 == 0) {\n return _line + 5;\n } else if (_line < 0 && (-_line) % 10 == 0) {\n return _line - 5;\n } else {\n return _line;\n }\n }\n}\n" + }, + "contracts/libraries/ManagedByLink.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./Ownable.sol\";\n\nabstract contract ManagedByLink is Ownable {\n event LinkNodeChanged(address newLinkNode);\n\n address public linkNode;\n\n constructor(address _linkNode) {\n linkNode = _linkNode;\n }\n\n function setLinkNode(address _newLinkNode) external onlyOwner {\n linkNode = _newLinkNode;\n emit LinkNodeChanged(_newLinkNode);\n }\n\n modifier onlyLinkNode() {\n require(msg.sender == linkNode);\n _;\n }\n}\n" + }, + "contracts/libraries/CalculateLinesToBPoolOdds.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./SafeMathUint256.sol\";\nimport \"./SafeMathInt256.sol\";\n\nabstract contract CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant MAX_BPOOL_WEIGHT = 50e18;\n\n function ratioOdds(uint256[] memory _proportions) internal pure returns (uint256[] memory _odds) {\n uint256 _total = sum(_proportions);\n\n _odds = new uint256[](_proportions.length);\n for (uint256 i = 0; i < _proportions.length; i++) {\n _odds[i] = (MAX_BPOOL_WEIGHT).mul(_proportions[i]).div(_total);\n require(_odds[i] >= 1e18, \"min outcome weight is 2%\");\n }\n }\n\n function sum(uint256[] memory _numbers) private pure returns (uint256 _sum) {\n for (uint256 i = 0; i < _numbers.length; i++) {\n _sum += _numbers[i];\n }\n }\n\n function evenOdds(bool _invalid, uint256 _outcomes) internal pure returns (uint256[] memory _odds) {\n uint256 _size = _outcomes + (_invalid ? 1 : 0);\n _odds = new uint256[](_size);\n\n if (_invalid) _odds[0] = 1e18; // 2%\n\n uint256 _each = (_invalid ? 49e18 : 50e18) / _outcomes;\n for (uint256 i = _invalid ? 1 : 0; i < _size; i++) {\n _odds[i] = _each;\n }\n }\n\n function oddsFromLines(int256 _moneyline1, int256 _moneyline2) internal pure returns (uint256[] memory _odds) {\n uint256 _odds1 = __calcLineToOdds(_moneyline1);\n uint256 _odds2 = __calcLineToOdds(_moneyline2);\n\n uint256 _total = _odds1 + _odds2;\n\n _odds1 = uint256(49e18).mul(_odds1).div(_total);\n _odds2 = uint256(49e18).mul(_odds2).div(_total);\n\n // Moneyline odds are too skewed: would have under 2% odds.\n require(_odds1 >= 1e18);\n require(_odds2 >= 1e18);\n\n _odds = new uint256[](3);\n _odds[0] = 1e18; // Invalid, 2%\n _odds[1] = _odds1;\n _odds[2] = _odds2;\n }\n\n function __calcLineToOdds(int256 _line) internal pure returns (uint256) {\n if (_line < 0) {\n // favored\n uint256 _posLine = uint256(-_line);\n return _posLine.mul(49e18).div(_posLine.add(100)); // 49e18 * _line / (_line + 100)\n } else {\n // underdog\n return uint256(4900e18).div(uint256(_line).add(100)); // 49e18 * 100 / (_line + 100)\n }\n }\n}\n" + }, + "contracts/libraries/TokenNamesFromTeams.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./Sport.sol\";\n\nabstract contract TokenNamesFromTeams is Sport {\n uint256 constant Away = 1;\n uint256 constant Home = 2;\n\n function makeSportsMarket(\n string memory _noContestName,\n string memory _homeTeamName,\n string memory _awayTeamName,\n uint256[] memory _odds\n ) internal returns (uint256) {\n string[] memory _outcomeNames = makeOutcomeNames(_noContestName, _homeTeamName, _awayTeamName);\n return startMarket(msg.sender, _outcomeNames, _odds, true);\n }\n\n function makeOutcomeNames(\n string memory _noContestName,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) private pure returns (string[] memory _names) {\n _names = new string[](3);\n _names[NoContest] = _noContestName;\n _names[Away] = _awayTeamName;\n _names[Home] = _homeTeamName;\n }\n}\n" + }, + "@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.7.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "contracts/libraries/HasSpreadMarket.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../turbo/AbstractMarketFactoryV3.sol\";\nimport \"./Sport.sol\";\nimport \"./CalculateLinesToBPoolOdds.sol\";\nimport \"./TokenNamesFromTeams.sol\";\n\nabstract contract HasSpreadMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds, TokenNamesFromTeams {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 private spreadMarketType;\n string private noContestName;\n\n uint256 constant SpreadAway = 1;\n uint256 constant SpreadHome = 2;\n\n constructor(uint256 _marketType, string memory _noContestName) {\n spreadMarketType = _marketType;\n noContestName = _noContestName;\n }\n\n function makeSpreadMarket(string memory _homeTeamName, string memory _awayTeamName) internal returns (uint256) {\n return makeSportsMarket(noContestName, _homeTeamName, _awayTeamName, evenOdds(true, 2));\n }\n\n function resolveSpreadMarket(\n uint256 _marketId,\n int256 _line,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n uint256 _shareTokenIndex = calcSpreadWinner(_homeScore, _awayScore, _line);\n endMarket(_marketId, _shareTokenIndex);\n }\n\n function calcSpreadWinner(\n uint256 _homeScore,\n uint256 _awayScore,\n int256 _targetSpread\n ) internal pure returns (uint256) {\n int256 _adjustedHomeScore = int256(_homeScore) + int256(_targetSpread);\n\n if (_adjustedHomeScore > int256(_awayScore)) {\n return SpreadHome; // home spread greater\n } else if (_adjustedHomeScore < int256(_awayScore)) {\n return SpreadAway; // away spread lesser\n } else {\n // draw / tie; some sports eliminate this with half-points\n return NoContest;\n }\n }\n}\n" + }, + "contracts/libraries/ResolveByScore.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./Sport.sol\";\nimport \"./ManagedByLink.sol\";\n\nabstract contract ResolvesByScore is Sport, ManagedByLink {\n function resolveEvent(\n uint256 _eventId,\n SportsEventStatus _eventStatus,\n uint256 _homeTeamId, // for verifying team stability\n uint256 _awayTeamId, // for verifying team stability\n uint256 _homeScore,\n uint256 _awayScore\n ) public onlyLinkNode {\n SportsEvent storage _event = sportsEvents[_eventId];\n\n require(_event.status == SportsEventStatus.Scheduled);\n require(uint8(_eventStatus) >= uint8(SportsEventStatus.Final));\n\n if (eventIsNoContest(_event, _eventStatus, _homeTeamId, _awayTeamId, WhoWonUnknown)) {\n resolveInvalidEvent(_eventId);\n } else {\n resolveValidEvent(_event, _homeScore, _awayScore);\n }\n\n _event.status = _eventStatus;\n _event.homeScore = _homeScore;\n _event.awayScore = _awayScore;\n }\n\n function resolveValidEvent(\n SportsEvent memory _event,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal virtual;\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/EnumerableSet.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n */\nlibrary EnumerableSet {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping (bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) { // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\n // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\n\n bytes32 lastvalue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastvalue;\n // Update the index for the moved value\n set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n require(set._values.length > index, \"EnumerableSet: index out of bounds\");\n return set._values[index];\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\nimport \"../utils/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.7.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "contracts/turbo/GroupFetcher.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./Fetcher.sol\";\nimport \"./Grouped.sol\";\n\nabstract contract GroupFetcher is Fetcher {\n struct SpecificMarketFactoryBundle {\n MarketFactoryBundle super;\n }\n\n struct StaticGroupBundle {\n uint256 id;\n string name;\n StaticMarketBundle[] markets;\n string[] marketNames;\n StaticMarketBundle invalidMarket;\n string invalidMarketName;\n uint256 endTime;\n string category;\n // Dynamics\n Grouped.GroupStatus status;\n }\n\n struct DynamicGroupBundle {\n uint256 id;\n Grouped.GroupStatus status;\n DynamicMarketBundle[] markets;\n DynamicMarketBundle invalidMarket;\n }\n\n function buildSpecificMarketFactoryBundle(address _marketFactory)\n internal\n view\n returns (SpecificMarketFactoryBundle memory _bundle)\n {\n _bundle.super = buildMarketFactoryBundle(AbstractMarketFactoryV3(_marketFactory));\n }\n\n function fetchInitial(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n SpecificMarketFactoryBundle memory _marketFactoryBundle,\n StaticGroupBundle[] memory _groupBundles,\n uint256 _lowestGroupIndex,\n uint256 _timestamp\n )\n {\n _marketFactoryBundle = buildSpecificMarketFactoryBundle(_marketFactory);\n (_groupBundles, _lowestGroupIndex) = buildStaticGroupBundles(\n _marketFactory,\n _ammFactory,\n _masterChef,\n _offset,\n _total\n );\n _timestamp = block.timestamp;\n }\n\n function fetchDynamic(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n )\n public\n view\n returns (\n DynamicGroupBundle[] memory _bundles,\n uint256 _lowestGroupIndex,\n uint256 _timestamp\n )\n {\n (_bundles, _lowestGroupIndex) = buildDynamicGroupBundles(_marketFactory, _ammFactory, _offset, _total);\n _timestamp = block.timestamp;\n }\n\n function buildStaticGroupBundles(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _offset,\n uint256 _total\n ) internal view returns (StaticGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\n uint256[] memory _groupIds;\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\n\n _total = _groupIds.length;\n _bundles = new StaticGroupBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildStaticGroupBundle(_marketFactory, _ammFactory, _masterChef, _groupIds[i]);\n }\n }\n\n function buildDynamicGroupBundles(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (DynamicGroupBundle[] memory _bundles, uint256 _lowestGroupIndex) {\n uint256[] memory _groupIds;\n (_groupIds, _lowestGroupIndex) = listOfInterestingGroups(_marketFactory, _offset, _total);\n\n _total = _groupIds.length;\n _bundles = new DynamicGroupBundle[](_total);\n for (uint256 i; i < _total; i++) {\n _bundles[i] = buildDynamicGroupBundle(_marketFactory, _ammFactory, _groupIds[i]);\n }\n }\n\n function buildStaticGroupBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n MasterChef _masterChef,\n uint256 _groupId\n ) internal view returns (StaticGroupBundle memory _bundle) {\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\n\n StaticMarketBundle[] memory _markets = new StaticMarketBundle[](_group.markets.length);\n for (uint256 i = 0; i < _markets.length; i++) {\n _markets[i] = buildStaticMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _masterChef,\n _group.markets[i]\n );\n }\n\n _bundle.id = _groupId;\n _bundle.name = _group.name;\n _bundle.status = _group.status;\n _bundle.markets = _markets;\n _bundle.endTime = _group.endTime;\n _bundle.invalidMarket = buildStaticMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _masterChef,\n _group.invalidMarket\n );\n _bundle.invalidMarketName = _group.invalidMarketName;\n _bundle.marketNames = _group.marketNames;\n _bundle.category = _group.category;\n }\n\n function buildDynamicGroupBundle(\n address _marketFactory,\n AMMFactory _ammFactory,\n uint256 _groupId\n ) internal view returns (DynamicGroupBundle memory _bundle) {\n Grouped.MarketGroup memory _group = Grouped(_marketFactory).getGroup(_groupId);\n\n DynamicMarketBundle[] memory _markets = new DynamicMarketBundle[](_group.markets.length);\n for (uint256 i = 0; i < _markets.length; i++) {\n _markets[i] = buildDynamicMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _group.markets[i]\n );\n }\n\n _bundle.id = _groupId;\n _bundle.markets = _markets;\n _bundle.invalidMarket = buildDynamicMarketBundle(\n AbstractMarketFactoryV3(_marketFactory),\n _ammFactory,\n _group.invalidMarket\n );\n _bundle.status = _group.status;\n }\n\n // Starts from the end of the groups list because newer groups are more interesting.\n // _offset is skipping all groups, not just interesting groups\n function listOfInterestingGroups(\n address _marketFactory,\n uint256 _offset,\n uint256 _total\n ) internal view returns (uint256[] memory _interestingGroupIds, uint256 _groupIndex) {\n _interestingGroupIds = new uint256[](_total);\n\n uint256 _groupCount = Grouped(_marketFactory).groupCount();\n\n // No groups so return nothing. (needed to avoid integer underflow below)\n if (_groupCount == 0) {\n return (new uint256[](0), 0);\n }\n\n uint256 _max = _groupCount;\n\n // No remaining groups so return nothing. (needed to avoid integer underflow below)\n if (_offset > _max) {\n return (new uint256[](0), 0);\n }\n\n uint256 _collectedGroups = 0;\n _groupIndex = _max - _offset;\n while (true) {\n if (_collectedGroups >= _total) break;\n if (_groupIndex == 0) break;\n\n _groupIndex--; // starts out one too high, so this works\n\n (Grouped.MarketGroup memory _group, uint256 _groupId) =\n Grouped(_marketFactory).getGroupByIndex(_groupIndex);\n\n if (isGroupInteresting(_group, AbstractMarketFactoryV3(_marketFactory))) {\n _interestingGroupIds[_collectedGroups] = _groupId;\n _collectedGroups++;\n }\n }\n\n if (_total > _collectedGroups) {\n assembly {\n // shortens array\n mstore(_interestingGroupIds, _collectedGroups)\n }\n }\n }\n\n function isGroupInteresting(Grouped.MarketGroup memory _group, AbstractMarketFactoryV3 _marketFactory)\n private\n view\n returns (bool)\n {\n for (uint256 i = 0; i < _group.markets.length; i++) {\n uint256 _marketId = _group.markets[i];\n if (openOrHasWinningShares(_marketFactory, _marketId)) {\n return true;\n }\n }\n if (openOrHasWinningShares(_marketFactory, _group.invalidMarket)) {\n return true;\n }\n\n return false;\n }\n}\n\ncontract GroupedFetcher is GroupFetcher {\n constructor() Fetcher(\"Grouped\", \"TBD\") {}\n}\n" + }, + "contracts/turbo/Grouped.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\nimport \"./GroupFetcher.sol\";\n\nabstract contract Grouped is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds {\n event GroupCreated(uint256 indexed id, uint256 endTime, uint256 invalidMarketId, string invalidMarketName);\n event GroupMarketAdded(uint256 indexed groupId, uint256 marketId, string marketName);\n event GroupFinalizing(uint256 indexed groupId, uint256 winningMarketIndex);\n event GroupResolved(uint256 indexed id, bool valid);\n\n enum GroupStatus {Unknown, Scheduled, Finalizing, Final, Invalid}\n\n struct MarketGroup {\n GroupStatus status;\n string name;\n uint256[] markets;\n string[] marketNames;\n uint256 invalidMarket;\n string invalidMarketName;\n uint256 endTime;\n string category;\n uint256 winningMarketIndex; // ignore when status is Scheduled. MAX_UINT is invalid\n }\n // GroupId => MarketGroup\n mapping(uint256 => MarketGroup) public marketGroups;\n uint256[] public listOfMarketGroups;\n\n // For regular markets, YES means the team won and NO means the team did not win.\n // For the invalid market, YES means none of the teams won and NO means a team won.\n uint256 constant OUTCOME_NO = 0;\n uint256 constant OUTCOME_YES = 1;\n\n uint256 constant MAX_UINT = 2**256 - 1;\n\n function groupCount() public view returns (uint256) {\n return listOfMarketGroups.length;\n }\n\n function getGroup(uint256 _groupId) public view returns (MarketGroup memory) {\n return marketGroups[_groupId];\n }\n\n function getGroupByIndex(uint256 _index) public view returns (MarketGroup memory _group, uint256 _groupId) {\n _groupId = listOfMarketGroups[_index];\n _group = getGroup(_groupId);\n }\n\n function startCreatingMarketGroup(\n uint256 _groupId,\n string memory _groupName,\n uint256 _endTime,\n string memory _invalidMarketName,\n string memory _category\n ) internal {\n require(marketGroups[_groupId].status == GroupStatus.Unknown, \"group exists\");\n\n listOfMarketGroups.push(_groupId);\n marketGroups[_groupId].status = GroupStatus.Scheduled;\n marketGroups[_groupId].name = _groupName;\n marketGroups[_groupId].endTime = _endTime;\n marketGroups[_groupId].category = _category;\n\n uint256 _invalidMarket = startMarket(msg.sender, buildOutcomesNames(_invalidMarketName), invalidOdds(), true);\n marketGroups[_groupId].invalidMarket = _invalidMarket;\n marketGroups[_groupId].invalidMarketName = _invalidMarketName;\n\n emit GroupCreated(_groupId, _endTime, _invalidMarket, _invalidMarketName);\n emit GroupMarketAdded(_groupId, _invalidMarket, _invalidMarketName);\n }\n\n function addMarketToMarketGroup(\n uint256 _groupId,\n string memory _marketName,\n uint256[] memory _odds\n ) internal {\n require(marketGroups[_groupId].status == GroupStatus.Scheduled, \"group must be Scheduled\");\n\n uint256 _marketId = startMarket(msg.sender, buildOutcomesNames(_marketName), _odds, true);\n marketGroups[_groupId].markets.push(_marketId);\n marketGroups[_groupId].marketNames.push(_marketName);\n emit GroupMarketAdded(_groupId, _marketId, _marketName);\n }\n\n // Use MAX_UINT for _winningMarketIndex to indicate INVALID\n function startResolvingMarketGroup(uint256 _groupId, uint256 _winningMarketIndex) internal {\n bool _isInvalid = _winningMarketIndex == MAX_UINT;\n MarketGroup memory _group = marketGroups[_groupId];\n\n require(_group.status == GroupStatus.Scheduled, \"group not Scheduled\");\n\n resolveInvalidMarket(_group, _isInvalid);\n marketGroups[_groupId].status = GroupStatus.Finalizing;\n marketGroups[_groupId].winningMarketIndex = _winningMarketIndex;\n emit GroupFinalizing(_groupId, _winningMarketIndex);\n }\n\n function resolveFinalizingGroupMarket(uint256 _groupId, uint256 _marketIndex) internal {\n MarketGroup memory _group = marketGroups[_groupId];\n require(_group.status == GroupStatus.Finalizing, \"must be finalizing\");\n\n uint256 _marketId = _group.markets[_marketIndex];\n bool _wins = _marketIndex == _group.winningMarketIndex;\n resolveGroupMarket(_marketId, _wins);\n }\n\n function finalizeMarketGroup(uint256 _groupId) internal {\n MarketGroup storage _group = marketGroups[_groupId];\n require(_group.status == GroupStatus.Finalizing);\n\n bool _valid = _group.winningMarketIndex != MAX_UINT;\n\n _group.status = _valid ? GroupStatus.Final : GroupStatus.Invalid;\n\n emit GroupResolved(_groupId, _valid);\n }\n\n function resolveGroupMarket(uint256 _marketId, bool _wins) internal {\n uint256 _winningOutcome = _wins ? OUTCOME_YES : OUTCOME_NO;\n endMarket(_marketId, _winningOutcome);\n }\n\n function resolveInvalidMarket(MarketGroup memory _group, bool _invalid) private {\n uint256 _outcomeIndex = _invalid ? OUTCOME_YES : OUTCOME_NO;\n endMarket(_group.invalidMarket, _outcomeIndex);\n }\n\n function buildOutcomesNames(string memory _marketName) internal pure returns (string[] memory _names) {\n _names = new string[](2);\n _names[OUTCOME_NO] = string(abi.encodePacked(\"NO - \", _marketName));\n _names[OUTCOME_YES] = string(abi.encodePacked(\"YES - \", _marketName));\n }\n\n function invalidOdds() private pure returns (uint256[] memory _odds) {\n _odds = new uint256[](2);\n _odds[OUTCOME_YES] = 1e18;\n _odds[OUTCOME_NO] = 49e18;\n }\n}\n" + }, + "contracts/turbo/GroupedMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"./Grouped.sol\";\nimport \"../libraries/ManagedByLink.sol\";\nimport \"../libraries/Versioned.sol\";\n\ncontract GroupedMarketFactoryV3 is AbstractMarketFactoryV3, Grouped, ManagedByLink, Versioned {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.2.0\")\n ManagedByLink(_linkNode)\n {}\n\n function initializeGroup(\n uint256 _groupId,\n string memory _groupName,\n string memory _invalidMarketName,\n uint256 _endTime,\n string memory _category\n ) public onlyLinkNode {\n startCreatingMarketGroup(_groupId, _groupName, _endTime, _invalidMarketName, _category);\n }\n\n function addOutcomesToGroup(\n uint256 _groupId,\n string[] memory _marketNames,\n uint256[][] memory _odds\n ) public onlyLinkNode {\n require(_marketNames.length == _odds.length);\n\n for (uint256 i = 0; i < _marketNames.length; i++) {\n addMarketToMarketGroup(_groupId, _marketNames[i], _odds[i]);\n }\n }\n\n // Set _winner to MAX_UINT (2*256 - 1) to indicate invalid\n function beginResolvingGroup(uint256 _groupId, uint256 _winningMarketIndex) public onlyLinkNode {\n startResolvingMarketGroup(_groupId, _winningMarketIndex);\n }\n\n function resolveMarkets(uint256 _groupId, uint256[] memory _marketIndexes) public onlyLinkNode {\n MarketGroup memory _group = marketGroups[_groupId];\n require(_group.status == GroupStatus.Finalizing);\n\n for (uint256 i = 0; i < _marketIndexes.length; i++) {\n uint256 _marketIndex = _marketIndexes[i];\n uint256 _marketId = _group.markets[_marketIndex];\n if (isMarketResolved(_marketId)) continue; // skip resolved markets\n resolveFinalizingGroupMarket(_groupId, _marketIndex);\n }\n }\n\n function finalizeGroup(uint256 _groupId) public onlyLinkNode {\n finalizeMarketGroup(_groupId);\n }\n\n // Used when some markets in a group can resolve early as NO.\n // ex: Teams eliminated early from a tournament cannot win the overall tournament.\n function resolveMarketAsNo(uint256 _marketId) public onlyLinkNode {\n require(markets[_marketId].active, \"market inactive\");\n resolveGroupMarket(_marketId, false);\n }\n\n function getRewardEndTime(uint256 _eventId) public view override returns (uint256) {\n return 0;\n }\n}\n" + }, + "contracts/turbo/TrustedMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\nimport \"../libraries/Versioned.sol\";\n\ncontract TrustedMarketFactoryV3 is AbstractMarketFactoryV3, CalculateLinesToBPoolOdds, Versioned {\n using SafeMathUint256 for uint256;\n\n struct MarketDetails {\n string description;\n }\n MarketDetails[] internal marketDetails;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol\n ) AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol) Versioned(\"v1.1.0\") {}\n\n function createMarket(\n address _creator,\n string calldata _description,\n string[] calldata _names,\n uint256[] calldata _odds\n ) public onlyOwner returns (uint256) {\n marketDetails.push(MarketDetails(_description));\n return startMarket(_creator, _names, _odds, true);\n }\n\n function trustedResolveMarket(uint256 _id, uint256 _winningOutcome) public onlyOwner {\n endMarket(_id, _winningOutcome);\n }\n\n function getMarketDetails(uint256 _id) public view returns (MarketDetails memory) {\n return marketDetails[_id];\n }\n\n function getRewardEndTime(uint256 _marketId) public view override returns (uint256) {\n return 0;\n }\n}\n" + }, + "contracts/turbo/TrustedMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV2.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\n\ncontract TrustedMarketFactoryV2 is AbstractMarketFactoryV2, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n\n event MarketCreated(uint256 id, address creator, uint256 _endTime, string description, string[] outcomes);\n event MarketResolved(uint256 id, address winner);\n\n struct MarketDetails {\n string description;\n }\n MarketDetails[] internal marketDetails;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee\n )\n AbstractMarketFactoryV2(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {}\n\n function createMarket(\n address _creator,\n uint256 _endTime,\n string calldata _description,\n string[] calldata _names,\n string[] calldata _symbols,\n uint256[] calldata _odds\n ) public onlyOwner returns (uint256) {\n require(\n _names.length == _symbols.length && _symbols.length == _odds.length,\n \"names, symbols, and odds must be the same length\"\n );\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _names, _symbols, _endTime, _odds));\n marketDetails.push(MarketDetails(_description));\n\n emit MarketCreated(_id, _creator, _endTime, _description, _symbols);\n return _id;\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Only the TrustedMarketFactory owner can resolve the market, using trustedResolveMarket\");\n }\n\n function trustedResolveMarket(uint256 _id, uint256 _winningOutcome) public onlyOwner {\n OwnedERC20 _winner = markets[_id].shareTokens[_winningOutcome];\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function getMarketDetails(uint256 _id) public view returns (MarketDetails memory) {\n return marketDetails[_id];\n }\n}\n" + }, + "contracts/turbo/AbstractMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./TurboShareTokenFactory.sol\";\nimport \"./FeePot.sol\";\n\nabstract contract AbstractMarketFactoryV2 is TurboShareTokenFactoryV1, Ownable {\n using SafeMathUint256 for uint256;\n\n // Should always have ID. Others are optional.\n // event MarketCreated(uint256 id, address settlementAddress, uint256 endTime, ...);\n\n // Should always have ID. Others are optional.\n // event MarketResolved(uint256 id, ...);\n\n event SharesMinted(uint256 id, uint256 amount, address receiver);\n event SharesBurned(uint256 id, uint256 amount, address receiver);\n event WinningsClaimed(\n uint256 id,\n address winningOutcome,\n uint256 amount,\n uint256 settlementFee,\n uint256 payout,\n address indexed receiver\n );\n\n event SettlementFeeClaimed(address settlementAddress, uint256 amount, address indexed receiver);\n event ProtocolFeeClaimed(address protocol, uint256 amount);\n\n event ProtocolChanged(address protocol);\n event ProtocolFeeChanged(uint256 fee);\n event SettlementFeeChanged(uint256 fee);\n event StakerFeeChanged(uint256 fee);\n\n IERC20Full public collateral;\n FeePot public feePot;\n\n // fees are out of 1e18 and only apply to new markets\n uint256 public stakerFee;\n uint256 public settlementFee;\n uint256 public protocolFee;\n\n address public protocol; // collects protocol fees\n\n uint256 public accumulatedProtocolFee = 0;\n // settlement address => amount of collateral\n mapping(address => uint256) public accumulatedSettlementFees;\n\n // How many shares equals one collateral.\n // Necessary to account for math errors from small numbers in balancer.\n // shares = collateral / shareFactor\n // collateral = shares * shareFactor\n uint256 public shareFactor;\n\n struct Market {\n address settlementAddress;\n OwnedERC20[] shareTokens;\n uint256 endTime;\n OwnedERC20 winner;\n uint256 settlementFee;\n uint256 protocolFee;\n uint256 stakerFee;\n uint256 creationTimestamp;\n uint256[] initialOdds;\n }\n Market[] internal markets;\n\n uint256 private constant MAX_UINT = 2**256 - 1;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee\n ) {\n owner = _owner; // controls fees for new markets\n collateral = _collateral;\n shareFactor = _shareFactor;\n feePot = _feePot;\n stakerFee = _stakerFee;\n settlementFee = _settlementFee;\n protocol = _protocol;\n protocolFee = _protocolFee;\n\n _collateral.approve(address(_feePot), MAX_UINT);\n\n // First market is always empty so that marketid zero means \"no market\"\n makeEmptyMarket();\n }\n\n function makeEmptyMarket() internal {\n string[] memory _noStrings = new string[](0);\n uint256[] memory _noUint256s = new uint256[](0);\n markets.push(makeMarket(address(0), _noStrings, _noStrings, 0, _noUint256s));\n }\n\n // function createMarket(address _settlementAddress, uint256 _endTime, ...) public returns (uint256);\n\n function resolveMarket(uint256 _id) public virtual;\n\n // Returns an empty struct if the market doesn't exist.\n // Can check market existence before calling this by comparing _id against markets.length.\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\n function getMarket(uint256 _id) public view returns (Market memory) {\n if (_id >= markets.length) {\n return Market(address(0), new OwnedERC20[](0), 0, OwnedERC20(0), 0, 0, 0, 0, new uint256[](0));\n } else {\n return markets[_id];\n }\n }\n\n function marketCount() public view returns (uint256) {\n return markets.length;\n }\n\n // Returns factory-specific details about a market.\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\n\n function mintShares(\n uint256 _id,\n uint256 _shareToMint,\n address _receiver\n ) public {\n require(markets.length > _id, \"No such market\");\n require(!isMarketResolved(_id), \"Cannot mint shares for resolved market\");\n\n uint256 _cost = calcCost(_shareToMint);\n collateral.transferFrom(msg.sender, address(this), _cost);\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\n }\n\n emit SharesMinted(_id, _shareToMint, _receiver);\n }\n\n function burnShares(\n uint256 _id,\n uint256 _sharesToBurn,\n address _receiver\n ) public returns (uint256) {\n require(markets.length > _id, \"No such market\");\n require(!isMarketResolved(_id), \"Cannot burn shares for resolved market\");\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n // errors if sender doesn't have enough shares\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\n }\n\n uint256 _payout = calcCost(_sharesToBurn);\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\n\n accumulatedProtocolFee += _protocolFee;\n collateral.transfer(_receiver, _payout);\n feePot.depositFees(_stakerFee);\n\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\n return _payout;\n }\n\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\n if (!isMarketResolved(_id)) {\n // errors if market does not exist or is not resolved or resolvable\n resolveMarket(_id);\n }\n\n Market memory _market = markets[_id];\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\n\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\n _payout = _payout.sub(_settlementFee);\n\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\n collateral.transfer(_receiver, _payout);\n\n emit WinningsClaimed(_id, address(_market.winner), _winningShares, _settlementFee, _payout, _receiver);\n return _payout;\n }\n\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\n uint256 _totalWinnings = 0;\n for (uint256 i = 0; i < _ids.length; i++) {\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\n }\n return _totalWinnings;\n }\n\n function claimSettlementFees(address _receiver) public returns (uint256) {\n uint256 _fees = accumulatedSettlementFees[msg.sender];\n if (_fees > 0) {\n accumulatedSettlementFees[msg.sender] = 0;\n collateral.transfer(_receiver, _fees);\n emit SettlementFeeClaimed(msg.sender, _fees, _receiver);\n }\n return _fees;\n }\n\n function claimProtocolFees() public returns (uint256) {\n require(msg.sender == protocol || msg.sender == address(this), \"Only protocol can claim protocol fee\");\n uint256 _fees = accumulatedProtocolFee;\n if (_fees > 0) {\n accumulatedProtocolFee = 0;\n collateral.transfer(protocol, _fees);\n emit ProtocolFeeClaimed(protocol, _fees);\n }\n return _fees;\n }\n\n function setSettlementFee(uint256 _newFee) external onlyOwner {\n settlementFee = _newFee;\n emit SettlementFeeChanged(_newFee);\n }\n\n function setStakerFee(uint256 _newFee) external onlyOwner {\n stakerFee = _newFee;\n emit StakerFeeChanged(_newFee);\n }\n\n function setProtocolFee(uint256 _newFee) external onlyOwner {\n protocolFee = _newFee;\n emit ProtocolFeeChanged(_newFee);\n }\n\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\n if (_claimFirst) {\n claimProtocolFees();\n }\n protocol = _newProtocol;\n emit ProtocolChanged(_newProtocol);\n }\n\n function makeMarket(\n address _settlementAddress,\n string[] memory _names,\n string[] memory _symbols,\n uint256 _endTime,\n uint256[] memory _initialOdds\n ) internal returns (Market memory _market) {\n _market = Market(\n _settlementAddress,\n createShareTokens(_names, _symbols, address(this)),\n _endTime,\n OwnedERC20(0),\n settlementFee,\n protocolFee,\n stakerFee,\n block.timestamp,\n _initialOdds\n );\n }\n\n function isMarketResolved(uint256 _id) public view returns (bool) {\n Market memory _market = markets[_id];\n return _market.winner != OwnedERC20(0);\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n function listUnresolvedMarkets() public view returns (uint256[] memory) {\n uint256 _totalUnresolved = 0;\n for (uint256 i = 0; i < markets.length; i++) {\n if (!isMarketResolved(i)) {\n _totalUnresolved++;\n }\n }\n\n uint256[] memory _marketIds = new uint256[](_totalUnresolved);\n\n uint256 n = 0;\n for (uint256 i = 0; i < markets.length; i++) {\n if (n >= _totalUnresolved) break;\n\n if (!isMarketResolved(i)) {\n _marketIds[n] = i;\n n++;\n }\n }\n\n return _marketIds;\n }\n\n // shares => collateral\n function calcCost(uint256 _shares) public view returns (uint256) {\n require(\n _shares >= shareFactor && _shares % shareFactor == 0,\n \"Shares must be both greater than (or equal to) and divisible by shareFactor\"\n );\n return _shares / shareFactor;\n }\n\n // collateral => shares\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\n return _collateralIn * shareFactor;\n }\n\n function onTransferOwnership(address, address) internal override {}\n}\n" + }, + "contracts/turbo/SportsLinkMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV2.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\n\ncontract SportsLinkMarketFactoryV2 is AbstractMarketFactoryV2, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event MarketCreated(\n uint256 id,\n address creator,\n uint256 endTime,\n MarketType marketType,\n uint256 indexed eventId,\n uint256 homeTeamId,\n uint256 awayTeamId,\n uint256 estimatedStartTime,\n int256 score\n );\n event MarketResolved(uint256 id, address winner);\n event LinkNodeChanged(address newLinkNode);\n\n enum MarketType {HeadToHead, Spread, OverUnder}\n enum HeadToHeadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum SpreadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum OverUnderOutcome {\n NoContest, // 0\n Over, // 1\n Under // 2\n }\n struct MarketDetails {\n uint256 eventId;\n uint256 homeTeamId;\n uint256 awayTeamId;\n uint256 estimatedStartTime;\n MarketType marketType;\n EventStatus eventStatus;\n // This value depends on the marketType.\n // HeadToHead: ignored\n // Spread: the home team spread\n // OverUnder: total score in game\n int256 value0;\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n enum EventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\n struct EventDetails {\n uint256[3] markets;\n uint256 startTime;\n uint256 homeScore;\n uint256 awayScore;\n EventStatus status;\n // If there is a resolution time then the market is resolved but not necessarily finalized.\n // A market is finalized when its last two score updates were identical.\n // Score updates must occur after a period of time spedcified by resolutionBuffer.\n // This mechanism exists to reduce the risk of bad scores being sent by the API then later corrected.\n // The downside is slower resolution.\n uint256 resolutionTime; // time since last score update\n bool finalized; // true after event resolves and has stable scores\n }\n // EventId => EventDetails\n mapping(uint256 => EventDetails) public events;\n uint256[] public listOfEvents;\n\n address public linkNode;\n uint256 public sportId;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee,\n address _linkNode,\n uint256 _sportId\n )\n AbstractMarketFactoryV2(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {\n linkNode = _linkNode;\n sportId = _sportId;\n }\n\n function createMarket(\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread,\n uint256 _totalScore,\n bool _makeSpread,\n bool _makeTotalScore,\n int256[2] memory _moneylines // [home,away]\n ) public returns (uint256[3] memory _ids) {\n require(msg.sender == linkNode, \"Only link node can create markets\");\n\n address _creator = msg.sender;\n uint256 _endTime = _startTimestamp.add(60 * 8); // 8 hours\n\n _ids = events[_eventId].markets;\n\n if (_ids[0] == 0 && _moneylines[0] != 0 && _moneylines[1] != 0) {\n _ids[0] = createHeadToHeadMarket(\n _creator,\n _endTime,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _moneylines\n );\n }\n\n if (_ids[1] == 0 && _makeSpread) {\n // spread market hasn't been created and is ready to be created\n _ids[1] = createSpreadMarket(\n _creator,\n _endTime,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n }\n\n if (_ids[2] == 0 && _makeTotalScore) {\n // over-under market hasn't been created and is ready to be created\n _ids[2] = createOverUnderMarket(\n _creator,\n _endTime,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _totalScore\n );\n }\n\n events[_eventId].status = EventStatus.Scheduled;\n events[_eventId].startTime = _startTimestamp;\n events[_eventId].markets = _ids;\n listOfEvents.push(_eventId);\n }\n\n function createHeadToHeadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(HeadToHeadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(HeadToHeadOutcome.Away)] = \"Away\";\n _outcomes[uint256(HeadToHeadOutcome.Home)] = \"Home\";\n\n uint256 _id = markets.length;\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\n markets.push(\n makeMarket(_creator, _outcomes, _outcomes, _endTime, oddsFromLines(_moneylines[1], _moneylines[0]))\n );\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.HeadToHead,\n EventStatus.Scheduled,\n 0\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.HeadToHead,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n 0\n );\n return _id;\n }\n\n function createSpreadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(SpreadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(SpreadOutcome.Away)] = \"Away\";\n _outcomes[uint256(SpreadOutcome.Home)] = \"Home\";\n\n // The spread is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the spread is a whole number then make it a half point more extreme, to eliminate ties.\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\n if (_homeSpread >= 0 && _homeSpread % 10 == 0) {\n _homeSpread += 5;\n } else if (_homeSpread < 0 && (-_homeSpread) % 10 == 0) {\n _homeSpread -= 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime, evenOdds(true, 2)));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.Spread,\n EventStatus.Scheduled,\n _homeSpread\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.Spread,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n return _id;\n }\n\n function createOverUnderMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n uint256 _overUnderTotal\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(OverUnderOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(OverUnderOutcome.Over)] = \"Over\";\n _outcomes[uint256(OverUnderOutcome.Under)] = \"Under\";\n\n // The total is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the total is a whole number then make it a half point higher, to eliminate ties.\n // So 50 becomes 55 and 0 becomes 5.\n if (_overUnderTotal >= 0 && _overUnderTotal % 10 == 0) {\n _overUnderTotal += 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime, evenOdds(true, 2)));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.OverUnder,\n EventStatus.Scheduled,\n int256(_overUnderTotal)\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.OverUnder,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n int256(_overUnderTotal)\n );\n return _id;\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Only the link node can resolve the market, using trustedResolveMarkets\");\n }\n\n function trustedResolveMarkets(\n uint256 _eventId,\n uint256 _eventStatus,\n uint256 _homeScore,\n uint256 _awayScore\n ) public {\n require(msg.sender == linkNode, \"Only link node can resolve markets\");\n\n EventDetails storage _event = events[_eventId];\n uint256[3] memory _ids = _event.markets;\n\n require(_ids[0] != 0 || _ids[1] != 0 || _ids[2] != 0, \"Cannot resolve markets that weren't created\");\n\n require(EventStatus(_eventStatus) != EventStatus.Scheduled, \"cannot resolve SCHEDULED markets\");\n\n // resolve markets as No Contest\n if (EventStatus(_eventStatus) != EventStatus.Final) {\n for (uint256 i = 0; i < _ids.length; i++) {\n uint256 _id = _ids[i];\n if (_id == 0) continue; // skip non-created markets\n OwnedERC20 _winner = markets[_id].shareTokens[0]; // 0th outcome is No Contest for all market types\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n return;\n }\n\n // only resolve markets that were created\n if (_ids[0] != 0) {\n resolveHeadToHeadMarket(_ids[0], _homeScore, _awayScore);\n }\n if (_ids[1] != 0) {\n resolveSpreadMarket(_ids[1], _homeScore, _awayScore);\n }\n if (_ids[2] != 0) {\n resolveOverUnderMarket(_ids[2], _homeScore, _awayScore);\n }\n }\n\n function resolveHeadToHeadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n OwnedERC20 _winner;\n if (_homeScore > _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Home)]; // home team won\n } else if (_homeScore < _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Away)]; // away team won\n } else {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveSpreadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetSpread = _details.value0;\n\n int256 _actualSpread = int256(_homeScore).sub(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualSpread > _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Home)]; // home spread greater\n } else if (_actualSpread < _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Away)]; // home spread lesser\n } else {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveOverUnderMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetTotal = _details.value0;\n\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualTotal > _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Over)]; // over\n } else if (_actualTotal < _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Under)]; // under\n } else {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n function setLinkNode(address _newLinkNode) external onlyOwner {\n linkNode = _newLinkNode;\n emit LinkNodeChanged(_newLinkNode);\n }\n\n function getEventMarkets(uint256 _eventId) external view returns (uint256[3] memory) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event;\n }\n\n // Events can be partially registered, by only creating some markets.\n // This returns true only if an event is fully registered.\n function isEventRegistered(uint256 _eventId) public view returns (bool) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event[0] != 0 && _event[1] != 0 && _event[2] != 0;\n }\n\n function isEventResolved(uint256 _eventId) public view returns (bool) {\n // check the event's head-to-head market since it will always exist if the event's markets exist\n uint256 _marketId = events[_eventId].markets[0];\n return isMarketResolved(_marketId);\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n // Lists all events that could be resolved with a call to resolveEvent.\n // Not all will be resolvable because this does not ensure the game ended.\n function listResolvableEvents() external view returns (uint256[] memory) {\n uint256 _totalResolvable = countResolvableEvents();\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\n\n uint256 n = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n if (n > _totalResolvable) break;\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _resolvableEvents[n] = _eventId;\n n++;\n }\n }\n\n return _resolvableEvents;\n }\n\n function countResolvableEvents() internal view returns (uint256) {\n uint256 _totalResolvable = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _totalResolvable++;\n }\n }\n return _totalResolvable;\n }\n\n // Returns true if a call to resolveEvent is potentially useful.\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\n EventDetails memory _event = events[_eventId];\n\n bool _unresolved = false; // default because non-existing markets aren't resolvable\n for (uint256 i = 0; i < _event.markets.length; i++) {\n uint256 _marketId = _event.markets[i];\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\n _unresolved = true;\n break;\n }\n }\n\n return _unresolved;\n }\n}\n" + }, + "contracts/turbo/SportsLinkMarketFactoryV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV1.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\n\ncontract SportsLinkMarketFactoryV1 is AbstractMarketFactoryV1 {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event MarketCreated(\n uint256 id,\n address creator,\n uint256 endTime,\n MarketType marketType,\n uint256 indexed eventId,\n uint256 homeTeamId,\n uint256 awayTeamId,\n uint256 estimatedStartTime,\n int256 score\n );\n event MarketResolved(uint256 id, address winner);\n event LinkNodeChanged(address newLinkNode);\n\n enum MarketType {HeadToHead, Spread, OverUnder}\n enum HeadToHeadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum SpreadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum OverUnderOutcome {\n NoContest, // 0\n Over, // 1\n Under // 2\n }\n struct MarketDetails {\n uint256 eventId;\n uint256 homeTeamId;\n uint256 awayTeamId;\n uint256 estimatedStartTime;\n MarketType marketType;\n EventStatus eventStatus;\n // This value depends on the marketType.\n // HeadToHead: ignored\n // Spread: the home team spread\n // OverUnder: total score in game\n int256 value0;\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n enum EventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\n struct EventDetails {\n uint256[3] markets;\n uint256 startTime;\n uint256 homeScore;\n uint256 awayScore;\n EventStatus status;\n // If there is a resolution time then the market is resolved but not necessarily finalized.\n // A market is finalized when its last two score updates were identical.\n // Score updates must occur after a period of time spedcified by resolutionBuffer.\n // This mechanism exists to reduce the risk of bad scores being sent by the API then later corrected.\n // The downside is slower resolution.\n uint256 resolutionTime; // time since last score update\n bool finalized; // true after event resolves and has stable scores\n }\n // EventId => EventDetails\n mapping(uint256 => EventDetails) public events;\n uint256[] public listOfEvents;\n\n address public linkNode;\n uint256 public sportId;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee,\n address _linkNode,\n uint256 _sportId\n )\n AbstractMarketFactoryV1(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {\n linkNode = _linkNode;\n sportId = _sportId;\n }\n\n function createMarket(\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread,\n uint256 _totalScore,\n bool _makeSpread,\n bool _makeTotalScore\n ) public returns (uint256[3] memory _ids) {\n require(msg.sender == linkNode, \"Only link node can create markets\");\n\n address _creator = msg.sender;\n uint256 _endTime = _startTimestamp.add(60 * 8); // 8 hours\n\n _ids = events[_eventId].markets;\n\n if (_ids[0] == 0) {\n _ids[0] = createHeadToHeadMarket(_creator, _endTime, _eventId, _homeTeamId, _awayTeamId, _startTimestamp);\n }\n\n if (_ids[1] == 0 && _makeSpread) {\n // spread market hasn't been created and is ready to be created\n _ids[1] = createSpreadMarket(\n _creator,\n _endTime,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n }\n\n if (_ids[2] == 0 && _makeTotalScore) {\n // over-under market hasn't been created and is ready to be created\n _ids[2] = createOverUnderMarket(\n _creator,\n _endTime,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _totalScore\n );\n }\n\n events[_eventId].status = EventStatus.Scheduled;\n events[_eventId].startTime = _startTimestamp;\n events[_eventId].markets = _ids;\n listOfEvents.push(_eventId);\n }\n\n function createHeadToHeadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(HeadToHeadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(HeadToHeadOutcome.Away)] = \"Away\";\n _outcomes[uint256(HeadToHeadOutcome.Home)] = \"Home\";\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.HeadToHead,\n EventStatus.Scheduled,\n 0\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.HeadToHead,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n 0\n );\n return _id;\n }\n\n function createSpreadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(SpreadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(SpreadOutcome.Away)] = \"Away\";\n _outcomes[uint256(SpreadOutcome.Home)] = \"Home\";\n\n // The spread is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the spread is a whole number then make it a half point more extreme, to eliminate ties.\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\n if (_homeSpread >= 0 && _homeSpread % 10 == 0) {\n _homeSpread += 5;\n } else if (_homeSpread < 0 && (-_homeSpread) % 10 == 0) {\n _homeSpread -= 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.Spread,\n EventStatus.Scheduled,\n _homeSpread\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.Spread,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n return _id;\n }\n\n function createOverUnderMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n uint256 _homeTeamId,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n uint256 _overUnderTotal\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(OverUnderOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(OverUnderOutcome.Over)] = \"Over\";\n _outcomes[uint256(OverUnderOutcome.Under)] = \"Under\";\n\n // The total is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the total is a whole number then make it a half point higher, to eliminate ties.\n // So 50 becomes 55 and 0 becomes 5.\n if (_overUnderTotal >= 0 && _overUnderTotal % 10 == 0) {\n _overUnderTotal += 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n MarketType.OverUnder,\n EventStatus.Scheduled,\n int256(_overUnderTotal)\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.OverUnder,\n _eventId,\n _homeTeamId,\n _awayTeamId,\n _startTimestamp,\n int256(_overUnderTotal)\n );\n return _id;\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Only the link node can resolve the market, using trustedResolveMarkets\");\n }\n\n function trustedResolveMarkets(\n uint256 _eventId,\n uint256 _eventStatus,\n uint256 _homeScore,\n uint256 _awayScore\n ) public {\n require(msg.sender == linkNode, \"Only link node can resolve markets\");\n\n EventDetails storage _event = events[_eventId];\n uint256[3] memory _ids = _event.markets;\n\n require(_ids[0] != 0 || _ids[1] != 0 || _ids[2] != 0, \"Cannot resolve markets that weren't created\");\n\n require(EventStatus(_eventStatus) != EventStatus.Scheduled, \"cannot resolve SCHEDULED markets\");\n\n // resolve markets as No Contest\n if (EventStatus(_eventStatus) != EventStatus.Final) {\n for (uint256 i = 0; i < _ids.length; i++) {\n uint256 _id = _ids[i];\n if (_id == 0) continue; // skip non-created markets\n OwnedERC20 _winner = markets[_id].shareTokens[0]; // 0th outcome is No Contest for all market types\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n return;\n }\n\n // only resolve markets that were created\n if (_ids[0] != 0) {\n resolveHeadToHeadMarket(_ids[0], _homeScore, _awayScore);\n }\n if (_ids[1] != 0) {\n resolveSpreadMarket(_ids[1], _homeScore, _awayScore);\n }\n if (_ids[2] != 0) {\n resolveOverUnderMarket(_ids[2], _homeScore, _awayScore);\n }\n }\n\n function resolveHeadToHeadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n OwnedERC20 _winner;\n if (_homeScore > _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Home)]; // home team won\n } else if (_homeScore < _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Away)]; // away team won\n } else {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveSpreadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetSpread = _details.value0;\n\n int256 _actualSpread = int256(_homeScore).sub(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualSpread > _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Home)]; // home spread greater\n } else if (_actualSpread < _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Away)]; // home spread lesser\n } else {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveOverUnderMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetTotal = _details.value0;\n\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualTotal > _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Over)]; // over\n } else if (_actualTotal < _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Under)]; // under\n } else {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n function setLinkNode(address _newLinkNode) external onlyOwner {\n linkNode = _newLinkNode;\n emit LinkNodeChanged(_newLinkNode);\n }\n\n function getEventMarkets(uint256 _eventId) external view returns (uint256[3] memory) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event;\n }\n\n // Events can be partially registered, by only creating some markets.\n // This returns true only if an event is fully registered.\n function isEventRegistered(uint256 _eventId) public view returns (bool) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event[0] != 0 && _event[1] != 0 && _event[2] != 0;\n }\n\n function isEventResolved(uint256 _eventId) public view returns (bool) {\n // check the event's head-to-head market since it will always exist if the event's markets exist\n uint256 _marketId = events[_eventId].markets[0];\n return isMarketResolved(_marketId);\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n // Lists all events that could be resolved with a call to resolveEvent.\n // Not all will be resolvable because this does not ensure the game ended.\n function listResolvableEvents() external view returns (uint256[] memory) {\n uint256 _totalResolvable = countResolvableEvents();\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\n\n uint256 n = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n if (n > _totalResolvable) break;\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _resolvableEvents[n] = _eventId;\n n++;\n }\n }\n\n return _resolvableEvents;\n }\n\n function countResolvableEvents() internal view returns (uint256) {\n uint256 _totalResolvable = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _totalResolvable++;\n }\n }\n return _totalResolvable;\n }\n\n // Returns true if a call to resolveEvent is potentially useful.\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\n EventDetails memory _event = events[_eventId];\n\n bool _unresolved = false; // default because non-existing markets aren't resolvable\n for (uint256 i = 0; i < _event.markets.length; i++) {\n uint256 _marketId = _event.markets[i];\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\n _unresolved = true;\n break;\n }\n }\n\n return _unresolved;\n }\n}\n" + }, + "contracts/turbo/AbstractMarketFactoryV1.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./TurboShareTokenFactory.sol\";\nimport \"./FeePot.sol\";\n\nabstract contract AbstractMarketFactoryV1 is TurboShareTokenFactoryV1, Ownable {\n using SafeMathUint256 for uint256;\n\n // Should always have ID. Others are optional.\n // event MarketCreated(uint256 id, address settlementAddress, uint256 endTime, ...);\n\n // Should always have ID. Others are optional.\n // event MarketResolved(uint256 id, ...);\n\n event SharesMinted(uint256 id, uint256 amount, address receiver);\n event SharesBurned(uint256 id, uint256 amount, address receiver);\n event WinningsClaimed(\n uint256 id,\n address winningOutcome,\n uint256 amount,\n uint256 settlementFee,\n uint256 payout,\n address indexed receiver\n );\n\n event SettlementFeeClaimed(address settlementAddress, uint256 amount, address indexed receiver);\n event ProtocolFeeClaimed(address protocol, uint256 amount);\n\n event ProtocolChanged(address protocol);\n event ProtocolFeeChanged(uint256 fee);\n event SettlementFeeChanged(uint256 fee);\n event StakerFeeChanged(uint256 fee);\n\n IERC20Full public collateral;\n FeePot public feePot;\n\n // fees are out of 1e18 and only apply to new markets\n uint256 public stakerFee;\n uint256 public settlementFee;\n uint256 public protocolFee;\n\n address public protocol; // collects protocol fees\n\n uint256 public accumulatedProtocolFee = 0;\n // settlement address => amount of collateral\n mapping(address => uint256) public accumulatedSettlementFees;\n\n // How many shares equals one collateral.\n // Necessary to account for math errors from small numbers in balancer.\n // shares = collateral / shareFactor\n // collateral = shares * shareFactor\n uint256 public shareFactor;\n\n struct Market {\n address settlementAddress;\n OwnedERC20[] shareTokens;\n uint256 endTime;\n OwnedERC20 winner;\n uint256 settlementFee;\n uint256 protocolFee;\n uint256 stakerFee;\n uint256 creationTimestamp;\n }\n Market[] internal markets;\n\n uint256 private constant MAX_UINT = 2**256 - 1;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee\n ) {\n owner = _owner; // controls fees for new markets\n collateral = _collateral;\n shareFactor = _shareFactor;\n feePot = _feePot;\n stakerFee = _stakerFee;\n settlementFee = _settlementFee;\n protocol = _protocol;\n protocolFee = _protocolFee;\n\n _collateral.approve(address(_feePot), MAX_UINT);\n\n // First market is always empty so that marketid zero means \"no market\"\n string[] memory _nothing = new string[](0);\n markets.push(makeMarket(address(0), _nothing, _nothing, 0));\n }\n\n // function createMarket(address _settlementAddress, uint256 _endTime, ...) public returns (uint256);\n\n function resolveMarket(uint256 _id) public virtual;\n\n // Returns an empty struct if the market doesn't exist.\n // Can check market existence before calling this by comparing _id against markets.length.\n // Can check market existence of the return struct by checking that shareTokens[0] isn't the null address\n function getMarket(uint256 _id) public view returns (Market memory) {\n if (_id >= markets.length) {\n return Market(address(0), new OwnedERC20[](0), 0, OwnedERC20(0), 0, 0, 0, 0);\n } else {\n return markets[_id];\n }\n }\n\n function marketCount() public view returns (uint256) {\n return markets.length;\n }\n\n // Returns factory-specific details about a market.\n // function getMarketDetails(uint256 _id) public view returns (MarketDetails memory);\n\n function mintShares(\n uint256 _id,\n uint256 _shareToMint,\n address _receiver\n ) public {\n require(markets.length > _id, \"No such market\");\n require(!isMarketResolved(_id), \"Cannot mint shares for resolved market\");\n\n uint256 _cost = calcCost(_shareToMint);\n collateral.transferFrom(msg.sender, address(this), _cost);\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n _market.shareTokens[_i].trustedMint(_receiver, _shareToMint);\n }\n\n emit SharesMinted(_id, _shareToMint, _receiver);\n }\n\n function burnShares(\n uint256 _id,\n uint256 _sharesToBurn,\n address _receiver\n ) public returns (uint256) {\n require(markets.length > _id, \"No such market\");\n require(!isMarketResolved(_id), \"Cannot burn shares for resolved market\");\n\n Market memory _market = markets[_id];\n for (uint256 _i = 0; _i < _market.shareTokens.length; _i++) {\n // errors if sender doesn't have enough shares\n _market.shareTokens[_i].trustedBurn(msg.sender, _sharesToBurn);\n }\n\n uint256 _payout = calcCost(_sharesToBurn);\n uint256 _protocolFee = _payout.mul(_market.protocolFee).div(10**18);\n uint256 _stakerFee = _payout.mul(_market.stakerFee).div(10**18);\n _payout = _payout.sub(_protocolFee).sub(_stakerFee);\n\n accumulatedProtocolFee += _protocolFee;\n collateral.transfer(_receiver, _payout);\n feePot.depositFees(_stakerFee);\n\n emit SharesBurned(_id, _sharesToBurn, msg.sender);\n return _payout;\n }\n\n function claimWinnings(uint256 _id, address _receiver) public returns (uint256) {\n if (!isMarketResolved(_id)) {\n // errors if market does not exist or is not resolved or resolvable\n resolveMarket(_id);\n }\n\n Market memory _market = markets[_id];\n uint256 _winningShares = _market.winner.trustedBurnAll(msg.sender);\n _winningShares = (_winningShares / shareFactor) * shareFactor; // remove unusable dust\n\n uint256 _payout = calcCost(_winningShares); // will fail if there are no winnings to claim\n uint256 _settlementFee = _payout.mul(_market.settlementFee).div(10**18);\n _payout = _payout.sub(_settlementFee);\n\n accumulatedSettlementFees[_market.settlementAddress] += _settlementFee;\n collateral.transfer(_receiver, _payout);\n\n emit WinningsClaimed(_id, address(_market.winner), _winningShares, _settlementFee, _payout, _receiver);\n return _payout;\n }\n\n function claimManyWinnings(uint256[] memory _ids, address _receiver) public returns (uint256) {\n uint256 _totalWinnings = 0;\n for (uint256 i = 0; i < _ids.length; i++) {\n _totalWinnings = _totalWinnings.add(claimWinnings(_ids[i], _receiver));\n }\n return _totalWinnings;\n }\n\n function claimSettlementFees(address _receiver) public returns (uint256) {\n uint256 _fees = accumulatedSettlementFees[msg.sender];\n if (_fees > 0) {\n accumulatedSettlementFees[msg.sender] = 0;\n collateral.transfer(_receiver, _fees);\n emit SettlementFeeClaimed(msg.sender, _fees, _receiver);\n }\n return _fees;\n }\n\n function claimProtocolFees() public returns (uint256) {\n require(msg.sender == protocol || msg.sender == address(this), \"Only protocol can claim protocol fee\");\n uint256 _fees = accumulatedProtocolFee;\n if (_fees > 0) {\n accumulatedProtocolFee = 0;\n collateral.transfer(protocol, _fees);\n emit ProtocolFeeClaimed(protocol, _fees);\n }\n return _fees;\n }\n\n function setSettlementFee(uint256 _newFee) external onlyOwner {\n settlementFee = _newFee;\n emit SettlementFeeChanged(_newFee);\n }\n\n function setStakerFee(uint256 _newFee) external onlyOwner {\n stakerFee = _newFee;\n emit StakerFeeChanged(_newFee);\n }\n\n function setProtocolFee(uint256 _newFee) external onlyOwner {\n protocolFee = _newFee;\n emit ProtocolFeeChanged(_newFee);\n }\n\n function setProtocol(address _newProtocol, bool _claimFirst) external onlyOwner {\n if (_claimFirst) {\n claimProtocolFees();\n }\n protocol = _newProtocol;\n emit ProtocolChanged(_newProtocol);\n }\n\n function makeMarket(\n address _settlementAddress,\n string[] memory _names,\n string[] memory _symbols,\n uint256 _endTime\n ) internal returns (Market memory _market) {\n _market = Market(\n _settlementAddress,\n createShareTokens(_names, _symbols, address(this)),\n _endTime,\n OwnedERC20(0),\n settlementFee,\n protocolFee,\n stakerFee,\n block.timestamp\n );\n }\n\n function isMarketResolved(uint256 _id) public view returns (bool) {\n Market memory _market = markets[_id];\n return _market.winner != OwnedERC20(0);\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n function listUnresolvedMarkets() public view returns (uint256[] memory) {\n uint256 _totalUnresolved = 0;\n for (uint256 i = 0; i < markets.length; i++) {\n if (!isMarketResolved(i)) {\n _totalUnresolved++;\n }\n }\n\n uint256[] memory _marketIds = new uint256[](_totalUnresolved);\n\n uint256 n = 0;\n for (uint256 i = 0; i < markets.length; i++) {\n if (n >= _totalUnresolved) break;\n\n if (!isMarketResolved(i)) {\n _marketIds[n] = i;\n n++;\n }\n }\n\n return _marketIds;\n }\n\n // shares => collateral\n function calcCost(uint256 _shares) public view returns (uint256) {\n require(\n _shares >= shareFactor && _shares % shareFactor == 0,\n \"Shares must be both greater than (or equal to) and divisible by shareFactor\"\n );\n return _shares / shareFactor;\n }\n\n // collateral => shares\n function calcShares(uint256 _collateralIn) public view returns (uint256) {\n return _collateralIn * shareFactor;\n }\n\n function onTransferOwnership(address, address) internal override {}\n}\n" + }, + "contracts/turbo/NFLMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV2.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\n\ncontract NFLMarketFactoryV2 is AbstractMarketFactoryV2, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event MarketCreated(\n uint256 id,\n address creator,\n uint256 endTime,\n MarketType marketType,\n uint256 indexed eventId,\n string homeTeamName,\n uint256 homeTeamId,\n string awayTeamName,\n uint256 awayTeamId,\n uint256 estimatedStartTime,\n int256 score\n );\n event MarketResolved(uint256 id, address winner);\n event LinkNodeChanged(address newLinkNode);\n\n enum MarketType {HeadToHead, Spread, OverUnder}\n enum HeadToHeadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum SpreadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n enum OverUnderOutcome {\n NoContest, // 0\n Over, // 1\n Under // 2\n }\n struct MarketDetails {\n uint256 eventId;\n string homeTeamName;\n uint256 homeTeamId;\n string awayTeamName;\n uint256 awayTeamId;\n uint256 estimatedStartTime;\n MarketType marketType;\n EventStatus eventStatus;\n // This value depends on the marketType.\n // HeadToHead: ignored\n // Spread: the home team spread\n // OverUnder: total score in game\n int256 value0;\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n enum EventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\n struct EventDetails {\n uint256[3] markets;\n uint256 startTime;\n uint256 homeScore;\n uint256 awayScore;\n EventStatus status;\n // If there is a resolution time then the market is resolved but not necessarily finalized.\n // A market is finalized when its last two score updates were identical.\n // Score updates must occur after a period of time specified by resolutionBuffer.\n // This mechanism exists to reduce the risk of bad scores being sent by the API then later corrected.\n // The downside is slower resolution.\n uint256 resolutionTime; // time since last score update\n bool finalized; // true after event resolves and has stable scores\n }\n // EventId => EventDetails\n mapping(uint256 => EventDetails) public events;\n uint256[] public listOfEvents;\n\n address public linkNode;\n uint256 public sportId;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee,\n address _linkNode,\n uint256 _sportId\n )\n AbstractMarketFactoryV2(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {\n linkNode = _linkNode;\n sportId = _sportId;\n }\n\n function createMarket(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread,\n uint256 _totalScore,\n bool _makeSpread,\n bool _makeTotalScore,\n int256[2] memory _moneylines // [home,away]\n ) public returns (uint256[3] memory _ids) {\n require(msg.sender == linkNode, \"Only link node can create markets\");\n\n uint256 _endTime = _startTimestamp.add(60 * 8); // 8 hours\n\n _ids = events[_eventId].markets;\n\n if (_ids[0] == 0 && _moneylines[0] != 0 && _moneylines[1] != 0) {\n _ids[0] = createHeadToHeadMarket(\n msg.sender,\n _endTime,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n _moneylines\n );\n }\n\n if (_ids[1] == 0 && _makeSpread) {\n // spread market hasn't been created and is ready to be created\n _ids[1] = createSpreadMarket(\n msg.sender,\n _endTime,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n }\n\n if (_ids[2] == 0 && _makeTotalScore) {\n // over-under market hasn't been created and is ready to be created\n _ids[2] = createOverUnderMarket(\n msg.sender,\n _endTime,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n _totalScore\n );\n }\n\n events[_eventId].status = EventStatus.Scheduled;\n events[_eventId].startTime = _startTimestamp;\n events[_eventId].markets = _ids;\n listOfEvents.push(_eventId);\n }\n\n function createHeadToHeadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(HeadToHeadOutcome.NoContest)] = \"No Contest / Draw\";\n _outcomes[uint256(HeadToHeadOutcome.Away)] = _awayTeamName;\n _outcomes[uint256(HeadToHeadOutcome.Home)] = _homeTeamName;\n\n uint256 _id = markets.length;\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\n markets.push(\n makeMarket(_creator, _outcomes, _outcomes, _endTime, oddsFromLines(_moneylines[1], _moneylines[0]))\n );\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n MarketType.HeadToHead,\n EventStatus.Scheduled,\n 0\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.HeadToHead,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n 0\n );\n return _id;\n }\n\n function createSpreadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(SpreadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(SpreadOutcome.Away)] = _awayTeamName;\n _outcomes[uint256(SpreadOutcome.Home)] = _homeTeamName;\n\n // The spread is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the spread is a whole number then make it a half point more extreme, to eliminate ties.\n // So 50 becomes 55, -60 becomes -65, and 0 becomes 5.\n if (_homeSpread >= 0 && _homeSpread % 10 == 0) {\n _homeSpread += 5;\n } else if (_homeSpread < 0 && (-_homeSpread) % 10 == 0) {\n _homeSpread -= 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime, evenOdds(true, 2)));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n MarketType.Spread,\n EventStatus.Scheduled,\n _homeSpread\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.Spread,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n _homeSpread\n );\n return _id;\n }\n\n function createOverUnderMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n uint256 _overUnderTotal\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(OverUnderOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(OverUnderOutcome.Over)] = \"Over\";\n _outcomes[uint256(OverUnderOutcome.Under)] = \"Under\";\n\n // The total is a quantity of tenths. So 55 is 5.5 and -6 is -60.\n // If the total is a whole number then make it a half point higher, to eliminate ties.\n // So 50 becomes 55 and 0 becomes 5.\n if (_overUnderTotal >= 0 && _overUnderTotal % 10 == 0) {\n _overUnderTotal += 5;\n }\n\n uint256 _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _endTime, evenOdds(true, 2)));\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n MarketType.OverUnder,\n EventStatus.Scheduled,\n int256(_overUnderTotal)\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.OverUnder,\n _eventId,\n _homeTeamName,\n _homeTeamId,\n _awayTeamName,\n _awayTeamId,\n _startTimestamp,\n int256(_overUnderTotal)\n );\n return _id;\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Only the link node can resolve the market, using trustedResolveMarkets\");\n }\n\n function trustedResolveMarkets(\n uint256 _eventId,\n uint256 _eventStatus,\n uint256 _homeScore,\n uint256 _awayScore\n ) public {\n require(msg.sender == linkNode, \"Only link node can resolve markets\");\n\n EventDetails storage _event = events[_eventId];\n uint256[3] memory _ids = _event.markets;\n\n require(_ids[0] != 0 || _ids[1] != 0 || _ids[2] != 0, \"Cannot resolve markets that weren't created\");\n\n require(EventStatus(_eventStatus) != EventStatus.Scheduled, \"cannot resolve SCHEDULED markets\");\n\n // resolve markets as No Contest\n if (EventStatus(_eventStatus) != EventStatus.Final) {\n for (uint256 i = 0; i < _ids.length; i++) {\n uint256 _id = _ids[i];\n if (_id == 0) continue; // skip non-created markets\n OwnedERC20 _winner = markets[_id].shareTokens[0]; // 0th outcome is No Contest for all market types\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n return;\n }\n\n // only resolve markets that were created\n if (_ids[0] != 0) {\n resolveHeadToHeadMarket(_ids[0], _homeScore, _awayScore);\n }\n if (_ids[1] != 0) {\n resolveSpreadMarket(_ids[1], _homeScore, _awayScore);\n }\n if (_ids[2] != 0) {\n resolveOverUnderMarket(_ids[2], _homeScore, _awayScore);\n }\n }\n\n function resolveHeadToHeadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n OwnedERC20 _winner;\n if (_homeScore > _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Home)]; // home team won\n } else if (_homeScore < _awayScore) {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.Away)]; // away team won\n } else {\n _winner = markets[_id].shareTokens[uint256(HeadToHeadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveSpreadMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetSpread = _details.value0;\n\n int256 _actualSpread = int256(_homeScore).sub(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualSpread > _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Home)]; // home spread greater\n } else if (_actualSpread < _targetSpread) {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.Away)]; // home spread lesser\n } else {\n _winner = markets[_id].shareTokens[uint256(SpreadOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function resolveOverUnderMarket(\n uint256 _id,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n MarketDetails memory _details = marketDetails[_id];\n int256 _targetTotal = _details.value0;\n\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\n\n OwnedERC20 _winner;\n if (_actualTotal > _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Over)]; // over\n } else if (_actualTotal < _targetTotal) {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.Under)]; // under\n } else {\n _winner = markets[_id].shareTokens[uint256(OverUnderOutcome.NoContest)]; // no contest\n }\n\n markets[_id].winner = _winner;\n emit MarketResolved(_id, address(_winner));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n function setLinkNode(address _newLinkNode) external onlyOwner {\n linkNode = _newLinkNode;\n emit LinkNodeChanged(_newLinkNode);\n }\n\n function getEventMarkets(uint256 _eventId) external view returns (uint256[3] memory) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event;\n }\n\n // Events can be partially registered, by only creating some markets.\n // This returns true only if an event is fully registered.\n function isEventRegistered(uint256 _eventId) public view returns (bool) {\n uint256[3] memory _event = events[_eventId].markets;\n return _event[0] != 0 && _event[1] != 0 && _event[2] != 0;\n }\n\n function isEventResolved(uint256 _eventId) public view returns (bool) {\n // check the event's head-to-head market since it will always exist if the event's markets exist\n uint256 _marketId = events[_eventId].markets[0];\n return isMarketResolved(_marketId);\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n // Lists all events that could be resolved with a call to resolveEvent.\n // Not all will be resolvable because this does not ensure the game ended.\n function listResolvableEvents() external view returns (uint256[] memory) {\n uint256 _totalResolvable = countResolvableEvents();\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\n\n uint256 n = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n if (n > _totalResolvable) break;\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _resolvableEvents[n] = _eventId;\n n++;\n }\n }\n\n return _resolvableEvents;\n }\n\n function countResolvableEvents() internal view returns (uint256) {\n uint256 _totalResolvable = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _totalResolvable++;\n }\n }\n return _totalResolvable;\n }\n\n // Returns true if a call to resolveEvent is potentially useful.\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\n EventDetails memory _event = events[_eventId];\n\n bool _unresolved = false; // default because non-existing markets aren't resolvable\n for (uint256 i = 0; i < _event.markets.length; i++) {\n uint256 _marketId = _event.markets[i];\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\n _unresolved = true;\n break;\n }\n }\n\n return _unresolved;\n }\n}\n" + }, + "contracts/turbo/NFLMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/Sport.sol\";\nimport \"../libraries/HasHeadToHeadMarket.sol\";\nimport \"../libraries/HasSpreadMarket.sol\";\nimport \"../libraries/HasOverUnderMarket.sol\";\nimport \"../libraries/ResolveByScore.sol\";\nimport \"../libraries/Versioned.sol\";\n\n// NFL is standard except ties are fine: they become NoContestOrDraw.\n// As a consequence, half points are not added to the lines.\ncontract NFLMarketFactoryV3 is\n AbstractMarketFactoryV3,\n SportView,\n HasHeadToHeadMarket,\n HasSpreadMarket,\n HasOverUnderMarket,\n ResolvesByScore,\n Versioned\n{\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant HeadToHead = 0;\n uint256 constant Spread = 1;\n uint256 constant OverUnder = 2;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.2.0\")\n ManagedByLink(_linkNode)\n HasHeadToHeadMarket(HeadToHead, \"No Contest / Draw\")\n HasSpreadMarket(Spread, \"No Contest\")\n HasOverUnderMarket(OverUnder, \"No Contest\")\n {}\n\n function createEvent(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread,\n int256 _totalScore,\n int256[2] memory _moneylines // [home,away]\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\n makeSportsEvent(\n _eventId,\n _marketIds,\n build3Lines(_homeSpread, _totalScore),\n _startTimestamp,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName\n );\n }\n\n function makeMarkets(\n int256[2] memory _moneylines,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal returns (uint256[] memory _marketIds) {\n _marketIds = new uint256[](3);\n\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\n _marketIds[OverUnder] = makeOverUnderMarket();\n }\n\n function resolveValidEvent(\n SportsEvent memory _event,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal override {\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\n }\n}\n" + }, + "contracts/libraries/HasOverUnderMarket.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../turbo/AbstractMarketFactoryV3.sol\";\nimport \"./Sport.sol\";\nimport \"./CalculateLinesToBPoolOdds.sol\";\n\nabstract contract HasOverUnderMarket is AbstractMarketFactoryV3, Sport, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 private overUnderMarketType;\n string private noContestName;\n\n uint256 constant Over = 1;\n uint256 constant Under = 2;\n\n constructor(uint256 _marketType, string memory _noContestName) {\n overUnderMarketType = _marketType;\n noContestName = _noContestName;\n }\n\n function makeOverUnderMarket() internal returns (uint256) {\n string[] memory _outcomeNames = makeOutcomeNames(noContestName);\n return startMarket(msg.sender, _outcomeNames, evenOdds(true, 2), true);\n }\n\n function resolveOverUnderMarket(\n uint256 _marketId,\n int256 _line,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal {\n uint256 _shareTokenIndex = calcOverUnderWinner(_homeScore, _awayScore, _line);\n endMarket(_marketId, _shareTokenIndex);\n }\n\n function calcOverUnderWinner(\n uint256 _homeScore,\n uint256 _awayScore,\n int256 _targetTotal\n ) internal pure returns (uint256) {\n int256 _actualTotal = int256(_homeScore).add(int256(_awayScore));\n\n if (_actualTotal > _targetTotal) {\n return Over; // total score above than line\n } else if (_actualTotal < _targetTotal) {\n return Under; // total score below line\n } else {\n return NoContest; // draw / tie; some sports eliminate this with half-points\n }\n }\n\n function makeOutcomeNames(string memory _noContestName) private pure returns (string[] memory _names) {\n _names = new string[](3);\n _names[NoContest] = _noContestName;\n _names[Over] = \"Over\";\n _names[Under] = \"Under\";\n }\n}\n" + }, + "contracts/turbo/NCAAFBMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/Sport.sol\";\nimport \"../libraries/HasHeadToHeadMarket.sol\";\nimport \"../libraries/HasSpreadMarket.sol\";\nimport \"../libraries/HasOverUnderMarket.sol\";\nimport \"../libraries/ResolveByScore.sol\";\nimport \"../libraries/Versioned.sol\";\n\n// NCAA-FB is identical to NFL except there are no ties.\n// As a consequence, spread and over-under lines add a half-point,\n// and the invalid outcome is just No Contest.\ncontract NCAAFBMarketFactoryV3 is\n AbstractMarketFactoryV3,\n SportView,\n HasHeadToHeadMarket,\n HasSpreadMarket,\n HasOverUnderMarket,\n ResolvesByScore,\n Versioned\n{\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant HeadToHead = 0;\n uint256 constant Spread = 1;\n uint256 constant OverUnder = 2;\n string constant InvalidName = \"No Contest\";\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.2.0\")\n ManagedByLink(_linkNode)\n HasHeadToHeadMarket(HeadToHead, InvalidName)\n HasSpreadMarket(Spread, InvalidName)\n HasOverUnderMarket(OverUnder, InvalidName)\n {}\n\n function createEvent(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256 _homeSpread,\n int256 _totalScore,\n int256[2] memory _moneylines // [home,away]\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\n makeSportsEvent(\n _eventId,\n _marketIds,\n build3Lines(_homeSpread, _totalScore),\n _startTimestamp,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName\n );\n }\n\n function makeMarkets(\n int256[2] memory _moneylines,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal returns (uint256[] memory _marketIds) {\n _marketIds = new uint256[](3);\n\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\n _marketIds[Spread] = makeSpreadMarket(_homeTeamName, _awayTeamName);\n _marketIds[OverUnder] = makeOverUnderMarket();\n }\n\n function resolveValidEvent(\n SportsEvent memory _event,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal override {\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\n resolveSpreadMarket(_event.markets[Spread], _event.lines[Spread], _homeScore, _awayScore);\n resolveOverUnderMarket(_event.markets[OverUnder], _event.lines[OverUnder], _homeScore, _awayScore);\n }\n}\n" + }, + "contracts/turbo/MLBMarketFactoryV3.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV3.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/Sport.sol\";\nimport \"../libraries/HasHeadToHeadMarket.sol\";\nimport \"../libraries/ResolveByScore.sol\";\nimport \"../libraries/Versioned.sol\";\n\ncontract MLBMarketFactoryV3 is AbstractMarketFactoryV3, SportView, HasHeadToHeadMarket, ResolvesByScore, Versioned {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n uint256 constant HeadToHead = 0;\n string constant InvalidName = \"No Contest\";\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256[3] memory _fees,\n address _protocol,\n address _linkNode\n )\n AbstractMarketFactoryV3(_owner, _collateral, _shareFactor, _feePot, _fees, _protocol)\n Versioned(\"v1.4.0\")\n ManagedByLink(_linkNode)\n HasHeadToHeadMarket(HeadToHead, InvalidName)\n {}\n\n function createEvent(\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeTeamId,\n string memory _awayTeamName,\n uint256 _awayTeamId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) public onlyLinkNode returns (uint256[] memory _marketIds) {\n _marketIds = makeMarkets(_moneylines, _homeTeamName, _awayTeamName);\n makeSportsEvent(\n _eventId,\n _marketIds,\n build1Line(),\n _startTimestamp,\n _homeTeamId,\n _awayTeamId,\n _homeTeamName,\n _awayTeamName\n );\n }\n\n function makeMarkets(\n int256[2] memory _moneylines,\n string memory _homeTeamName,\n string memory _awayTeamName\n ) internal returns (uint256[] memory _marketIds) {\n _marketIds = new uint256[](1);\n _marketIds[HeadToHead] = makeHeadToHeadMarket(_moneylines, _homeTeamName, _awayTeamName);\n }\n\n function resolveValidEvent(\n SportsEvent memory _event,\n uint256 _homeScore,\n uint256 _awayScore\n ) internal override {\n resolveHeadToHeadMarket(_event.markets[HeadToHead], _homeScore, _awayScore);\n }\n}\n" + }, + "contracts/turbo/MMALinkMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV2.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\n\ncontract MMALinkMarketFactoryV2 is AbstractMarketFactoryV2, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event MarketCreated(\n uint256 id,\n address creator,\n uint256 endTime,\n MarketType marketType,\n uint256 indexed eventId,\n string homeFighterName,\n uint256 homeFighterId,\n string awayFighterName,\n uint256 awayFighterId,\n uint256 estimatedStartTime\n );\n event MarketResolved(uint256 id, address winner);\n event LinkNodeChanged(address newLinkNode);\n\n enum MarketType {HeadToHead}\n enum HeadToHeadOutcome {\n NoContest, // 0\n Away, // 1\n Home // 2\n }\n\n struct MarketDetails {\n uint256 eventId;\n string homeFighterName;\n uint256 homeFighterId;\n string awayFighterName;\n uint256 awayFighterId;\n uint256 estimatedStartTime;\n MarketType marketType;\n EventStatus eventStatus;\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n enum EventStatus {Unknown, Scheduled, Final, Postponed, Canceled}\n struct EventDetails {\n uint256[1] markets;\n uint256 homeFighterId;\n uint256 awayFighterId;\n uint256 startTime;\n EventStatus eventStatus;\n }\n\n // EventId => EventDetails\n mapping(uint256 => EventDetails) public events;\n uint256[] public listOfEvents;\n\n address public linkNode;\n uint256 public sportId;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee,\n address _linkNode,\n uint256 _sportId\n )\n AbstractMarketFactoryV2(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {\n linkNode = _linkNode;\n sportId = _sportId;\n }\n\n function createMarket(\n uint256 _eventId,\n string memory _homeFighterName,\n uint256 _homeFighterId,\n string memory _awayFighterName,\n uint256 _awayFighterId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) public {\n require(msg.sender == linkNode, \"Only link node can create markets\");\n\n address _creator = msg.sender;\n uint256 _endTime = _startTimestamp.add(60 * 8); // 8 hours\n\n uint256[1] memory _ids = events[_eventId].markets;\n // require(_ids[0] == 0, \"This event was already used to create markets\");\n\n _ids[0] = createHeadToHeadMarket(\n _creator,\n _endTime,\n _eventId,\n _homeFighterName,\n _homeFighterId,\n _awayFighterName,\n _awayFighterId,\n _startTimestamp,\n _moneylines\n );\n\n events[_eventId].markets = _ids;\n events[_eventId].homeFighterId = _homeFighterId;\n events[_eventId].awayFighterId = _awayFighterId;\n events[_eventId].startTime = _startTimestamp;\n events[_eventId].eventStatus = EventStatus.Scheduled;\n listOfEvents.push(_eventId);\n }\n\n function createHeadToHeadMarket(\n address _creator,\n uint256 _endTime,\n uint256 _eventId,\n string memory _homeTeamName,\n uint256 _homeFighterId,\n string memory _awayTeamName,\n uint256 _awayFighterId,\n uint256 _startTimestamp,\n int256[2] memory _moneylines // [home,away]\n ) internal returns (uint256) {\n string[] memory _outcomes = new string[](3);\n _outcomes[uint256(HeadToHeadOutcome.NoContest)] = \"No Contest\";\n _outcomes[uint256(HeadToHeadOutcome.Away)] = _awayTeamName;\n _outcomes[uint256(HeadToHeadOutcome.Home)] = _homeTeamName;\n\n uint256 _id = markets.length;\n // moneylines is [home,away] but the outcomes are listed [NC,away,home] so they must be reversed\n markets.push(\n makeMarket(_creator, _outcomes, _outcomes, _endTime, oddsFromLines(_moneylines[1], _moneylines[0]))\n );\n marketDetails[_id] = MarketDetails(\n _eventId,\n _homeTeamName,\n _homeFighterId,\n _awayTeamName,\n _awayFighterId,\n _startTimestamp,\n MarketType.HeadToHead,\n EventStatus.Scheduled\n );\n emit MarketCreated(\n _id,\n _creator,\n _endTime,\n MarketType.HeadToHead,\n _eventId,\n _homeTeamName,\n _homeFighterId,\n _awayTeamName,\n _awayFighterId,\n _startTimestamp\n );\n return _id;\n }\n\n enum WhoWon {Unknown, Home, Away, Draw}\n\n function trustedResolveMarkets(\n uint256 _eventId,\n EventStatus _eventStatus,\n uint256 _homeFighterId,\n uint256 _awayFighterId,\n WhoWon _whoWon\n ) public {\n require(msg.sender == linkNode, \"Only link node can resolve markets\");\n\n EventDetails memory _event = events[_eventId];\n require(_event.markets[0] != 0, \"Cannot resolve markets that weren't created\");\n require(EventStatus(_eventStatus) != EventStatus.Scheduled, \"Cannot resolve SCHEDULED markets\");\n\n if (eventIsNoContest(_event, _eventStatus, _homeFighterId, _awayFighterId, _whoWon)) {\n resolveMarketsAsNoContest(_eventId);\n } else {\n resolveHeadToHeadMarket(_event.markets[0], _whoWon);\n }\n\n events[_eventId].eventStatus = _eventStatus;\n }\n\n function eventIsNoContest(\n EventDetails memory _event,\n EventStatus _eventStatus,\n uint256 _homeFighterId,\n uint256 _awayFighterId,\n WhoWon _whoWon\n ) internal pure returns (bool) {\n bool _draw = _whoWon == WhoWon.Draw;\n bool _notFinal = _eventStatus != EventStatus.Final;\n bool _unstableHomeFighterId = _event.homeFighterId != _homeFighterId;\n bool _unstableAwayFighterId = _event.awayFighterId != _awayFighterId;\n return _draw || _notFinal || _unstableHomeFighterId || _unstableAwayFighterId;\n }\n\n function resolveMarketsAsNoContest(uint256 _eventId) internal {\n uint256[1] memory _marketIds = events[_eventId].markets;\n for (uint256 i = 0; i < _marketIds.length; i++) {\n uint256 _marketId = _marketIds[i];\n if (_marketId == 0) continue; // skip non-created markets\n OwnedERC20 _winner = markets[_marketId].shareTokens[0]; // 0th outcome is No Contest for all market types\n markets[_marketId].winner = _winner;\n emit MarketResolved(_marketId, address(_winner));\n }\n }\n\n function resolveHeadToHeadMarket(uint256 _marketId, WhoWon _whoWon) internal {\n OwnedERC20 _winner;\n if (WhoWon.Home == _whoWon) {\n _winner = markets[_marketId].shareTokens[uint256(HeadToHeadOutcome.Home)];\n } else if (WhoWon.Away == _whoWon) {\n _winner = markets[_marketId].shareTokens[uint256(HeadToHeadOutcome.Away)];\n } else {\n require(false, \"Bad market resolution choice\");\n }\n\n markets[_marketId].winner = _winner;\n emit MarketResolved(_marketId, address(_winner));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n // Only usable off-chain. Gas cost can easily eclipse block limit.\n // Lists all events that could be resolved with a call to resolveEvent.\n // Not all will be resolvable because this does not ensure the game ended.\n function listResolvableEvents() external view returns (uint256[] memory) {\n uint256 _totalResolvable = countResolvableEvents();\n uint256[] memory _resolvableEvents = new uint256[](_totalResolvable);\n\n uint256 n = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n if (n > _totalResolvable) break;\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _resolvableEvents[n] = _eventId;\n n++;\n }\n }\n\n return _resolvableEvents;\n }\n\n function countResolvableEvents() internal view returns (uint256) {\n uint256 _totalResolvable = 0;\n for (uint256 i = 0; i < listOfEvents.length; i++) {\n uint256 _eventId = listOfEvents[i];\n if (isEventResolvable(_eventId)) {\n _totalResolvable++;\n }\n }\n return _totalResolvable;\n }\n\n // Returns true if a call to resolveEvent is potentially useful.\n function isEventResolvable(uint256 _eventId) internal view returns (bool) {\n EventDetails memory _event = events[_eventId];\n\n bool _unresolved = false; // default because non-existing markets aren't resolvable\n for (uint256 i = 0; i < _event.markets.length; i++) {\n uint256 _marketId = _event.markets[i];\n if (_marketId != 0 && !isMarketResolved(_marketId)) {\n _unresolved = true;\n break;\n }\n }\n\n return _unresolved;\n }\n\n function getEvent(uint256 _eventId) external view returns (EventDetails memory _event) {\n _event = events[_eventId];\n }\n\n function setLinkNode(address _newLinkNode) external onlyOwner {\n linkNode = _newLinkNode;\n emit LinkNodeChanged(_newLinkNode);\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Only the link node can resolve the market, using trustedResolveMarkets\");\n }\n}\n" + }, + "contracts/turbo/CryptoMarketFactoryV2.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\npragma abicoder v2;\n\nimport \"../libraries/IERC20Full.sol\";\nimport \"../balancer/BPool.sol\";\nimport \"./AbstractMarketFactoryV2.sol\";\nimport \"./FeePot.sol\";\nimport \"../libraries/SafeMathInt256.sol\";\n\nimport \"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\";\nimport \"../libraries/CalculateLinesToBPoolOdds.sol\";\n\ncontract CryptoMarketFactoryV2 is AbstractMarketFactoryV2, CalculateLinesToBPoolOdds {\n using SafeMathUint256 for uint256;\n using SafeMathInt256 for int256;\n\n event MarketCreated(\n uint256 id,\n address creator,\n uint256 indexed endTime,\n MarketType marketType,\n uint256 indexed coinIndex,\n uint256 price\n );\n event MarketResolved(uint256 id, address winner);\n\n struct Coin {\n string name;\n AggregatorV3Interface priceFeed;\n uint256 price;\n uint8 imprecision; // how many decimals to truncate\n uint256[1] currentMarkets;\n }\n Coin[] public coins;\n\n enum MarketType {\n PriceUpDown // 0\n }\n enum PriceUpDownOutcome {\n Above, // 0\n NotAbove // 1\n }\n struct MarketDetails {\n MarketType marketType;\n uint256 coinIndex;\n uint256 creationPrice;\n uint256 resolutionPrice;\n }\n // MarketId => MarketDetails\n mapping(uint256 => MarketDetails) internal marketDetails;\n\n address public linkNode; // market creator and resolver\n\n uint256 public nextResolutionTime;\n\n constructor(\n address _owner,\n IERC20Full _collateral,\n uint256 _shareFactor,\n FeePot _feePot,\n uint256 _stakerFee,\n uint256 _settlementFee,\n address _protocol,\n uint256 _protocolFee,\n address _linkNode\n )\n AbstractMarketFactoryV2(\n _owner,\n _collateral,\n _shareFactor,\n _feePot,\n _stakerFee,\n _settlementFee,\n _protocol,\n _protocolFee\n )\n {\n linkNode = _linkNode;\n\n string memory _name = \"\";\n coins.push(makeCoin(_name, AggregatorV3Interface(0), 0));\n }\n\n function getMarketDetails(uint256 _marketId) public view returns (MarketDetails memory) {\n return marketDetails[_marketId];\n }\n\n // NOTE: Trusts the owner not to add a coin twice.\n // Returns the coin index.\n function addCoin(\n string calldata _name,\n AggregatorV3Interface _priceFeed,\n uint8 _imprecision\n ) external onlyOwner returns (uint256 _coinIndex) {\n Coin memory _coin = makeCoin(_name, _priceFeed, _imprecision);\n _coinIndex = coins.length;\n coins.push(_coin);\n }\n\n function getCoin(uint256 _coinIndex) public view returns (Coin memory _coin) {\n _coin = coins[_coinIndex];\n }\n\n function getCoins() public view returns (Coin[] memory _coins) {\n _coins = new Coin[](coins.length);\n // Skip first coin because it's always the zeroed-out fake coin.\n for (uint256 i = 1; i < coins.length; i++) {\n _coins[i] = coins[i];\n }\n }\n\n // Iterates over all coins.\n // If markets do not exist for coin, create them.\n // Unless _nextResolutionTime is zero; then do not create new markets.\n // If markets for coin exist and are ready to resolve, resolve them and create new markets.\n // Else, error.\n //\n // Assume that _roundIds has a dummy value at index 0, and is 1 indexed like the\n // coins array.\n function createAndResolveMarkets(uint80[] calldata _roundIds, uint256 _nextResolutionTime) public {\n require(msg.sender == linkNode, \"Only link node can create markets\");\n // If market creation was stopped then it can be started again.\n // If market creation wasn't stopped then you must wait for market end time to resolve.\n require(block.timestamp >= nextResolutionTime, \"Must wait for market resolution\");\n require(_roundIds.length == coins.length, \"Must specify one roundId for each coin\");\n\n uint256 _resolutionTime = nextResolutionTime;\n nextResolutionTime = _nextResolutionTime;\n\n // Start at 1 to skip the fake Coin in the 0 index\n for (uint256 i = 1; i < coins.length; i++) {\n createAndResolveMarketsForCoin(i, _resolutionTime, _roundIds[i]);\n }\n }\n\n function createAndResolveMarketsForCoin(\n uint256 _coinIndex,\n uint256 _resolutionTime,\n uint80 _roundId\n ) internal {\n Coin memory _coin = coins[_coinIndex];\n (uint256 _fullPrice, uint256 _newPrice) = getPrice(_coin, _roundId, _resolutionTime);\n\n // resolve markets\n if (_coin.currentMarkets[uint256(MarketType.PriceUpDown)] != 0) {\n resolvePriceUpDownMarket(_coin, _newPrice, _fullPrice);\n }\n\n // update price only AFTER resolution\n coins[_coinIndex].price = _newPrice;\n\n // link node sets nextResolutionTime to zero to signify \"do not create markets after resolution\"\n if (nextResolutionTime == 0) {\n return;\n }\n\n // create markets\n coins[_coinIndex].currentMarkets[uint256(MarketType.PriceUpDown)] = createPriceUpDownMarket(\n _coinIndex,\n linkNode,\n _newPrice\n );\n }\n\n function resolvePriceUpDownMarket(\n Coin memory _coin,\n uint256 _newPrice,\n uint256 _fullPrice\n ) internal {\n uint256 _marketId = _coin.currentMarkets[uint256(MarketType.PriceUpDown)];\n\n OwnedERC20 _winner;\n if (_newPrice > _coin.price) {\n _winner = markets[_marketId].shareTokens[uint256(PriceUpDownOutcome.Above)];\n } else {\n _winner = markets[_marketId].shareTokens[uint256(PriceUpDownOutcome.NotAbove)];\n }\n\n markets[_marketId].winner = _winner;\n marketDetails[_marketId].resolutionPrice = _fullPrice;\n emit MarketResolved(_marketId, address(_winner));\n }\n\n function createPriceUpDownMarket(\n uint256 _coinIndex,\n address _creator,\n uint256 _newPrice\n ) internal returns (uint256 _id) {\n string[] memory _outcomes = new string[](2);\n _outcomes[uint256(PriceUpDownOutcome.Above)] = \"Above\";\n _outcomes[uint256(PriceUpDownOutcome.NotAbove)] = \"Not Above\";\n\n uint256 _nextResolutionTime = nextResolutionTime;\n _id = markets.length;\n markets.push(makeMarket(_creator, _outcomes, _outcomes, _nextResolutionTime, evenOdds(false, 2)));\n marketDetails[_id] = MarketDetails(MarketType.PriceUpDown, _coinIndex, _newPrice, 0);\n emit MarketCreated(_id, _creator, _nextResolutionTime, MarketType.PriceUpDown, _coinIndex, _newPrice);\n }\n\n // Returns the price based on a few factors.\n // If _roundId is zero then it returns the latest price.\n // Else, it returns the price for that round,\n // but errors if that isn't the first round after the resolution time.\n // The price is then altered to match the desired precision.\n function getPrice(\n Coin memory _coin,\n uint80 _roundId,\n uint256 _resolutionTime\n ) internal view returns (uint256 _fullPrice, uint256 _truncatedPrice) {\n if (_roundId == 0) {\n (, int256 _rawPrice, , , ) = _coin.priceFeed.latestRoundData();\n require(_rawPrice >= 0, \"Price from feed is negative\");\n _fullPrice = uint256(_rawPrice);\n } else {\n (, int256 _rawPrice, , uint256 updatedAt, ) = _coin.priceFeed.getRoundData(_roundId);\n require(_rawPrice >= 0, \"Price from feed is negative\");\n require(updatedAt >= _resolutionTime, \"Price hasn't been updated yet\");\n\n // if resolution time is zero then market creation was stopped, so the previous round doesn't matter\n if (_resolutionTime != 0) {\n (, , , uint256 _previousRoundTime, ) = _coin.priceFeed.getRoundData(previousRound(_roundId));\n require(_previousRoundTime < _resolutionTime, \"Must use first round after resolution time\");\n }\n\n _fullPrice = uint256(_rawPrice);\n }\n\n // The precision is how many decimals the price has. Zero is dollars, 2 includes cents, 3 is tenths of a cent, etc.\n // Our resolution rules want a certain precision. Like BTC is to the dollar and MATIC is to the cent.\n // If somehow the decimals are larger than the desired precision then add zeroes to the end to meet the precision.\n // This does not change the resolution outcome but does guard against decimals() changing and therefore altering the basis.\n\n uint8 _precision = _coin.priceFeed.decimals(); // probably constant but that isn't guaranteed, so query each time\n if (_precision > _coin.imprecision) {\n uint8 _truncate = _precision - _coin.imprecision;\n _truncatedPrice = _fullPrice / (10**_truncate);\n } else if (_precision < _coin.imprecision) {\n uint8 _greaten = _coin.imprecision - _precision;\n _truncatedPrice = _fullPrice * (10**_greaten);\n } else {\n _truncatedPrice = _fullPrice;\n }\n\n // Round up because that cleanly fits Above/Not-Above.\n if (_truncatedPrice != _fullPrice) {\n _truncatedPrice += 1;\n }\n }\n\n function makeCoin(\n string memory _name,\n AggregatorV3Interface _priceFeed,\n uint8 _imprecision\n ) internal pure returns (Coin memory _coin) {\n uint256[1] memory _currentMarkets = [uint256(0)];\n _coin = Coin(_name, _priceFeed, 0, _imprecision, _currentMarkets);\n }\n\n function resolveMarket(uint256) public pure override {\n require(false, \"Use createAndResolveMarkets\");\n }\n\n // The roundId is the encoding of two parts: the phase and the phase-specific round id.\n // To find the previous roundId:\n // 1. extract the phase and phase-specific round (I call these _phaseId and _roundId)\n // 2. decrement the phase-specific round\n // 3. re-encode the phase and phase-specific round.\n uint256 private constant PHASE_OFFSET = 64;\n\n function previousRound(uint80 _fullRoundId) internal pure returns (uint80) {\n uint256 _phaseId = uint256(uint16(_fullRoundId >> PHASE_OFFSET));\n uint64 _roundId = uint64(_fullRoundId) - 1;\n return uint80((_phaseId << PHASE_OFFSET) | _roundId);\n }\n}\n" + }, + "contracts/libraries/FakePriceFeed.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol\";\n\ncontract FakePriceFeed is AggregatorV3Interface {\n uint8 decimals_;\n string description_;\n uint256 version_;\n\n struct Round {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n mapping(uint80 => Round) rounds;\n uint80 latestRoundId;\n\n constructor(\n uint8 _decimals,\n string memory _description,\n uint256 _version\n ) {\n decimals_ = _decimals;\n description_ = _description;\n version_ = _version;\n }\n\n function decimals() external view override returns (uint8) {\n return decimals_;\n }\n\n function description() external view override returns (string memory) {\n return description_;\n }\n\n function version() external view override returns (uint256) {\n return version_;\n }\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(uint80 roundId_)\n public\n view\n override\n returns (\n uint80 _roundId,\n int256 _answer,\n uint256 _startedAt,\n uint256 _updatedAt,\n uint80 _answeredInRound\n )\n {\n Round memory _round = rounds[roundId_];\n _roundId = _round.roundId;\n _answer = _round.answer;\n _startedAt = _round.startedAt;\n _updatedAt = _round.updatedAt;\n _answeredInRound = _round.answeredInRound;\n }\n\n function latestRoundData()\n public\n view\n override\n returns (\n uint80 _roundId,\n int256 _answer,\n uint256 _startedAt,\n uint256 _updatedAt,\n uint80 _answeredInRound\n )\n {\n return getRoundData(latestRoundId);\n }\n\n function addRound(\n uint80 _roundId,\n int256 _answer,\n uint256 _startedAt,\n uint256 _updatedAt,\n uint80 _answeredInRound\n ) external {\n rounds[_roundId] = Round(_roundId, _answer, _startedAt, _updatedAt, _answeredInRound);\n latestRoundId = _roundId;\n }\n}\n" + }, + "contracts/libraries/PlaceholderReputationToken.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title Cash\n * @dev Test contract for collateral\n */\ncontract PlaceholderReputationToken is ERC20 {\n uint8 private _decimals;\n\n constructor(\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) ERC20(name_, symbol_) {\n _decimals = decimals_;\n }\n\n function decimals() public view virtual override(ERC20) returns (uint8) {\n return _decimals;\n }\n}\n" + }, + "contracts/libraries/Cash.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/**\n * @title Cash\n * @dev Test contract for collateral\n */\ncontract Cash is ERC20 {\n uint8 private _decimals;\n\n constructor(\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) ERC20(name_, symbol_) {\n _decimals = decimals_;\n }\n\n function decimals() public view virtual override(ERC20) returns (uint8) {\n return _decimals;\n }\n\n function faucet(uint256 _amount) public returns (bool) {\n _mint(msg.sender, _amount);\n return true;\n }\n}\n" + }, + "contracts/balancer/BPoolForTesting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.7.6;\n\nimport \"./BFactory.sol\";\nimport \"../libraries/IERC20Full.sol\";\nimport \"../libraries/Cash.sol\";\n\ncontract BPoolForTesting {\n BFactory private bFactory;\n BPool private bPool;\n uint256 private constant MAX_UINT = 2**256 - 1;\n\n constructor(BFactory _bFactory) {\n bFactory = _bFactory;\n }\n\n function createBPoolForTesting(\n Cash[] calldata _tokens,\n uint256[] calldata _initialLiquidity,\n uint256[] calldata _weights\n ) external returns (BPool) {\n require(\n _tokens.length == _weights.length && _tokens.length == _initialLiquidity.length,\n \"Tokens, weights and initial liquidity should all have the same length.\"\n );\n\n bPool = bFactory.newBPool();\n\n for (uint256 i = 0; i < _tokens.length; i++) {\n _tokens[i].approve(address(bPool), MAX_UINT);\n bPool.bind(address(_tokens[i]), _initialLiquidity[i], _weights[i]);\n }\n\n bPool.finalize();\n\n return bPool;\n }\n\n function getBPool() external view returns (BPool) {\n return bPool;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file