Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xB900ff616a8183F868936Ff30c19d819a5043876
Balance 0 ETH
Nonce 1
Code Size 18804 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

18804 bytes
0x6080604052600436106102585763ffffffff60e060020a600035041663024c7ec781146102e45780630c7d5cd8146102fe5780630e53aae91461032c57806312c2aca41461038157806319b64015146103aa5780631cfab290146103de5780631e1401f8146103ff57806321e6b53d1461044257806322f3e2d4146104635780632fe8a6ad1461047857806338a5e0161461048d578063395900d4146104a25780633e8ff43f146104cc578063415f1240146104f857806349d10b64146105105780634af80f0e1461052557806354fd4d5014610546578063579cd3ca1461055b5780635e35359e1461057057806361cd756e1461059a57806367b6d57c146105af578063690d8320146105d05780636a49d2c4146105f15780636aa5332c1461061b57806371f52bf31461064557806379ba50971461065a5780637b1039991461066f5780637d8916bd146106845780638da5cb5b1461070757806394c275ad1461071c5780639b99a8e214610731578063a60e772414610746578063af94b8d81461079b578063b127c0a5146107c5578063b4a176d314610858578063bbb7e5d81461086d578063bf75455814610888578063c45d3d921461089d578063ca1d209d146108b2578063cdc91c69146108bd578063d031370b146108d2578063d260529c146108ea578063d3fb73b4146108ff578063d4ee1d9014610914578063d55ec69714610929578063d66bd5241461093e578063d89595121461095f578063dc8de37914610980578063e8dc12ff146109a1578063ecbca55d146109cb578063f2fde38b146109e9578063fc0c546a14610a0a575b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1615156102e2576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b005b3480156102f057600080fd5b506102e26004351515610a1f565b34801561030a57600080fd5b50610313610a67565b6040805163ffffffff9092168252519081900360200190f35b34801561033857600080fd5b5061034d600160a060020a0360043516610a73565b6040805195865263ffffffff9094166020860152911515848401521515606084015215156080830152519081900360a00190f35b34801561038d57600080fd5b50610396610b0e565b604080519115158252519081900360200190f35b3480156103b657600080fd5b506103c2600435610b57565b60408051600160a060020a039092168252519081900360200190f35b3480156103ea57600080fd5b50610313600160a060020a0360043516610b83565b34801561040b57600080fd5b50610429600160a060020a0360043581169060243516604435610bb5565b6040805192835260208301919091528051918290030190f35b34801561044e57600080fd5b506102e2600160a060020a0360043516610bcf565b34801561046f57600080fd5b50610396610be3565b34801561048457600080fd5b50610396610c7c565b34801561049957600080fd5b506102e2610c9d565b3480156104ae57600080fd5b506102e2600160a060020a0360043581169060243516604435610d0a565b3480156104d857600080fd5b506104e1610da9565b6040805161ffff9092168252519081900360200190f35b34801561050457600080fd5b506102e2600435610dae565b34801561051c57600080fd5b506102e2611002565b34801561053157600080fd5b506102e2600160a060020a036004351661126f565b34801561055257600080fd5b506104e16112b1565b34801561056757600080fd5b506103136112b6565b34801561057c57600080fd5b506102e2600160a060020a03600435811690602435166044356112ce565b3480156105a657600080fd5b506103c26113e8565b3480156105bb57600080fd5b506102e2600160a060020a03600435166113f7565b3480156105dc57600080fd5b506102e2600160a060020a036004351661149e565b3480156105fd57600080fd5b506102e2600160a060020a036004351663ffffffff602435166115bf565b34801561062757600080fd5b506106336004356117fe565b60408051918252519081900360200190f35b34801561065157600080fd5b506104e1611823565b34801561066657600080fd5b506102e2611832565b34801561067b57600080fd5b506103c26118f3565b604080516020600480358082013583810280860185019096528085526102e295369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975050933594506119029350505050565b34801561071357600080fd5b506103c2611c12565b34801561072857600080fd5b50610313611c21565b34801561073d57600080fd5b506104e1611c35565b34801561075257600080fd5b506040805160206004803580820135838102808601850190965280855261063395369593946024949385019291829185019084908082843750949750611c3b9650505050505050565b3480156107a757600080fd5b50610429600160a060020a0360043581169060243516604435611c91565b3480156107d157600080fd5b506040805160206004602480358281013584810280870186019097528086526102e296843596369660449591949091019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750611e369650505050505050565b34801561086457600080fd5b506102e2611f6f565b34801561087957600080fd5b50610633600435602435611fa8565b34801561089457600080fd5b50610396611fc2565b3480156108a957600080fd5b506103c2611fc7565b6102e2600435611fd6565b3480156108c957600080fd5b506102e26124ec565b3480156108de57600080fd5b506103c2600435612545565b3480156108f657600080fd5b50610396610da9565b34801561090b57600080fd5b506103c261256d565b34801561092057600080fd5b506103c261257c565b34801561093557600080fd5b506102e261258b565b34801561094a57600080fd5b5061034d600160a060020a0360043516612638565b34801561096b57600080fd5b50610633600160a060020a036004351661267e565b34801561098c57600080fd5b50610633600160a060020a036004351661268f565b610633600160a060020a0360043581169060243581169060443590606435811690608435166126b8565b3480156109d757600080fd5b506102e263ffffffff60043516612927565b3480156109f557600080fd5b506102e2600160a060020a0360043516612a1c565b348015610a1657600080fd5b506103c2612ab9565b610a27612ac8565b60038054911515740100000000000000000000000000000000000000000274ff000000000000000000000000000000000000000019909216919091179055565b60085463ffffffff1681565b6000806000806000610a8361483b565b50505050600160a060020a03929092166000908152600760209081526040808320815160a081018352815480825260019092015463ffffffff811694820185905260ff64010000000082048116151594830194909452650100000000008104841615156060830152660100000000000090049092161515608090920182905295919450919250829190565b6000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff1690565b6000600682815481101515610b6857fe5b600091825260209091200154600160a060020a031692915050565b600081610b8f81612b18565b5050600160a060020a031660009081526007602052604090206001015463ffffffff1690565b600080610bc3858585611c91565b91509150935093915050565b610bd7612ac8565b610be0816113f7565b50565b60048054604080517f8da5cb5b00000000000000000000000000000000000000000000000000000000815290516000933093600160a060020a031692638da5cb5b928183019260209282900301818887803b158015610c4157600080fd5b505af1158015610c55573d6000803e3d6000fd5b505050506040513d6020811015610c6b57600080fd5b5051600160a060020a031614905090565b60035474010000000000000000000000000000000000000000900460ff1681565b6001610ca7611c35565b61ffff1611610d00576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b610d08612b85565b565b610d12612ac8565b60048054604080517f5e35359e000000000000000000000000000000000000000000000000000000008152600160a060020a038781169482019490945285841660248201526044810185905290519290911691635e35359e9160648082019260009290919082900301818387803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050505050565b600190565b600060606000610dbc612b95565b6003805460a860020a60ff02191660a860020a17905560008411610e2a576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015610e7157600080fd5b505af1158015610e85573d6000803e3d6000fd5b505050506040513d6020811015610e9b57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929550600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015610f0c57600080fd5b505af1158015610f20573d6000803e3d6000fd5b50505050600680549050604051908082528060200260200182016040528015610f53578160200160208202803883390190505b509150600090505b8151811015610f865760018282815181101515610f7457fe5b60209081029091010152600101610f5b565b610fec6006805480602002602001604051908101604052809291908181526020018280548015610fdf57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610fc1575b5050505050838587612bf7565b50506003805460a860020a60ff02191690555050565b60008054600160a060020a0316331480611037575060035474010000000000000000000000000000000000000000900460ff16155b151561107b576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6110a47f436f6e7472616374526567697374727900000000000000000000000000000000612ebc565b600254909150600160a060020a038083169116148015906110cd5750600160a060020a03811615155b1515611123576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b604080517fbb34534c0000000000000000000000000000000000000000000000000000000081527f436f6e747261637452656769737472790000000000000000000000000000000060048201529051600091600160a060020a0384169163bb34534c9160248082019260209290919082900301818787803b1580156111a757600080fd5b505af11580156111bb573d6000803e3d6000fd5b505050506040513d60208110156111d157600080fd5b5051600160a060020a03161415611232576040805160e560020a62461bcd02815260206004820152601460248201527f4552525f494e56414c49445f5245474953545259000000000000000000000000604482015290519081900360640190fd5b6002805460038054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff19928316179092559091169216919091179055565b611277612ac8565b8061128181612f54565b506005805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b601e81565b60085468010000000000000000900463ffffffff1681565b60006112d8612b95565b6003805460a860020a60ff02191660a860020a1790556112f6612ac8565b61130d6000805160206148e9833981519152612ebc565b600160a060020a0385166000908152600760205260409020600101549091506601000000000000900460ff16158061134a5750611348610be3565b155b806113625750600054600160a060020a038281169116145b15156113a6576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b6113b1848484612fb5565b600160a060020a0384166000908152600760205260409020600101546601000000000000900460ff1615610fec57610fec84612fe6565b600354600160a060020a031681565b6113ff612ac8565b6000805160206148e9833981519152611417816130db565b60048054604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a03868116948201949094529051929091169163f2fde38b9160248082019260009290919082900301818387803b15801561148257600080fd5b505af1158015611496573d6000803e3d6000fd5b505050505050565b60006114a8612b95565b6003805460a860020a60ff02191660a860020a1790556114c6612ac8565b6000805160206148c98339815191526114de81612b18565b6114f56000805160206148e9833981519152612ebc565b91506114ff610be3565b15806115185750600054600160a060020a038381169116145b151561155c576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b604051600160a060020a03841690303180156108fc02916000818181858888f19350505050158015611592573d6000803e3d6000fd5b506115aa6000805160206148c9833981519152612fe6565b50506003805460a860020a60ff021916905550565b60006115c9612ac8565b6115d1613131565b826115db8161318e565b836115e581612f54565b836115ef816131ee565b600454600160a060020a038781169116148015906116335750600160a060020a0386166000908152600760205260409020600101546601000000000000900460ff16155b1515611677576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b60085463ffffffff908116620f424003811690861611156116e2576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61ffff6116ed611c35565b61ffff1610611746576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b505050600160a060020a0390921660008181526007602052604081208181556001908101805466ff0000000000001963ffffffff80881663ffffffff1993841617919091166601000000000000179092556006805493840181559093527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f909101805473ffffffffffffffffffffffffffffffffffffffff191690931790925560088054808416909401909216921691909117905550565b600080825b600081111561181c5760019190910190600a9004611803565b5092915050565b600061182d611c35565b905090565b600154600160a060020a03163314611882576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b60015460008054604051600160a060020a0393841693909116917f343765429aea5a34b3ff6a3785a98a5abb2597aca87bfbb58632c173d585373a91a3600180546000805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a03841617909155169055565b600254600160a060020a031681565b600080600061190f612b95565b6003805460a860020a60ff02191660a860020a17905561192d613263565b6119388686866132c1565b600092505b85518310156119f65785516000805160206148c98339815191529087908590811061196457fe5b90602001906020020151600160a060020a031614156119eb5734858481518110151561198c57fe5b60209081029091010151146119eb576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b60019092019161193d565b6000341115611a9b576000805160206148c983398151915260005260076020527fb2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0f546601000000000000900460ff161515611a9b576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4e4f5f4554485f524553455256450000000000000000000000000000604482015290519081900360640190fd5b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611ae257600080fd5b505af1158015611af6573d6000803e3d6000fd5b505050506040513d6020811015611b0c57600080fd5b50519150611b1b86868461357d565b905083811015611b75576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f52455455524e5f544f4f5f4c4f570000000000000000000000000000604482015290519081900360640190fd5b60048054604080517f867904b400000000000000000000000000000000000000000000000000000000815233938101939093526024830184905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b158015611be257600080fd5b505af1158015611bf6573d6000803e3d6000fd5b50506003805460a860020a60ff02191690555050505050505050565b600054600160a060020a031681565b600854640100000000900463ffffffff1681565b60065490565b80516000908190815b81811015611c7857611c6c8582815181101515611c5d57fe5b906020019060200201516117fe565b90920191600101611c44565b6001611c848484611fa8565b03600a0a95945050505050565b600080600080611c9f613263565b86611ca981612b18565b86611cb381612b18565b600160a060020a038981169089161415611d17576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b611d2e6000805160206148a9833981519152612ebc565b600160a060020a03166394491fab611d458b61268f565b600160a060020a038c1660009081526007602052604090206001015463ffffffff16611d708c61268f565b600160a060020a038d16600090815260076020908152604080832060010154815163ffffffff89811660e060020a028252600482019890985295871660248701526044860194909452949092166064840152608483018d9052925160a48084019492939192918390030190829087803b158015611dec57600080fd5b505af1158015611e00573d6000803e3d6000fd5b505050506040513d6020811015611e1657600080fd5b50519350611e23846135ac565b9384900399939850929650505050505050565b6000611e40612b95565b6003805460a860020a60ff02191660a860020a179055611e5e613263565b611e698383866132c1565b600480546040805160e060020a6318160ddd0281529051600160a060020a03909216926318160ddd9282820192602092908290030181600087803b158015611eb057600080fd5b505af1158015611ec4573d6000803e3d6000fd5b505050506040513d6020811015611eda57600080fd5b505160048054604080517fa24835d100000000000000000000000000000000000000000000000000000000815233938101939093526024830188905251929350600160a060020a03169163a24835d19160448082019260009290919082900301818387803b158015611f4b57600080fd5b505af1158015611f5f573d6000803e3d6000fd5b50505050610fec83838387612bf7565b611f77612ac8565b6003546002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909216919091179055565b600081600281048401811515611fba57fe5b049392505050565b600181565b600554600160a060020a031681565b600080600080600080600080600080611fed612b95565b6003805460a860020a60ff02191660a860020a17905561200b6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254612042903463ffffffff61362a16565b6000805160206148c983398151915260009081526007602090815260008051602061492983398151915292909255600480546040805160e060020a6318160ddd0281529051600160a060020a03909216946318160ddd948285019491939283900390910190829087803b1580156120b857600080fd5b505af11580156120cc573d6000803e3d6000fd5b505050506040513d60208110156120e257600080fd5b505199506120fd6000805160206148a9833981519152612ebc565b6006549099509750600096505b8787101561244a57600680548890811061212057fe5b9060005260206000200160009054906101000a9004600160a060020a031695506007600087600160a060020a0316600160a060020a0316815260200190815260200160002060000154945088600160a060020a031663ebbb21588b87600860009054906101000a900463ffffffff168f6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b1580156121ea57600080fd5b505af11580156121fe573d6000803e3d6000fd5b505050506040513d602081101561221457600080fd5b50519350600160a060020a0386166000805160206148c9833981519152141561237657833411156122745760405133903486900380156108fc02916000818181858888f1935050505015801561226e573d6000803e3d6000fd5b50612371565b833410156123715734156122d2576040805160e560020a62461bcd02815260206004820152601560248201527f4552525f494e56414c49445f4554485f56414c55450000000000000000000000604482015290519081900360640190fd5b6008546122fa906c010000000000000000000000009004600160a060020a031633308761368a565b6008600c9054906101000a9004600160a060020a0316600160a060020a0316632e1a7d4d856040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b15801561235857600080fd5b505af115801561236c573d6000803e3d6000fd5b505050505b612382565b6123828633308761368a565b612392858563ffffffff61377216565b600160a060020a038716600090815260076020526040902081905592506123bf8a8c63ffffffff61377216565b60408051868152602081018690528082018390529051919350600160a060020a0388169133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a350600160a060020a03851660009081526007602052604090206001015463ffffffff1661243f828785846137cf565b60019096019561210a565b60048054604080517f867904b40000000000000000000000000000000000000000000000000000000081523393810193909352602483018e905251600160a060020a039091169163867904b491604480830192600092919082900301818387803b1580156124b757600080fd5b505af11580156124cb573d6000803e3d6000fd5b50506003805460a860020a60ff021916905550505050505050505050505050565b6124f4612ac8565b6124fc61383e565b60045460408051600160a060020a0390921682526001602083015280517fa170412ae067fdeca19fd2204ce7eb66f723d827f4af15433b6f33f7fdc642bb9281900390910190a1565b600680548290811061255357fe5b600091825260209091200154600160a060020a0316905081565b600454600160a060020a031681565b600154600160a060020a031681565b6000612595612ac8565b6125ac6000805160206148e9833981519152612ebc565b90506125b781612a1c565b604080517f90f58c96000000000000000000000000000000000000000000000000000000008152601e60048201529051600160a060020a038316916390f58c9691602480830192600092919082900301818387803b15801561261857600080fd5b505af115801561262c573d6000803e3d6000fd5b50505050610be0611832565b6007602052600090815260409020805460019091015463ffffffff81169060ff640100000000820481169165010000000000810482169166010000000000009091041685565b60006126898261268f565b92915050565b60008161269b81612b18565b5050600160a060020a031660009081526007602052604090205490565b60006126c2612b95565b6003805460a860020a60ff02191660a860020a1790557f42616e636f724e6574776f726b00000000000000000000000000000000000000612702816130db565b600160a060020a038781169087161415612766576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f53414d455f534f555243455f54415247455400000000000000000000604482015290519081900360640190fd5b600554600160a060020a031615806128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b1580156127e157600080fd5b505af11580156127f5573d6000803e3d6000fd5b505050506040513d602081101561280b57600080fd5b505180156128a95750600554604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015291519190921691633af32abf9160248083019260209291908290030181600087803b15801561287c57600080fd5b505af1158015612890573d6000803e3d6000fd5b505050506040513d60208110156128a657600080fd5b50515b15156128ff576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f4e4f545f57484954454c495354454400000000000000000000000000604482015290519081900360640190fd5b61290c8787878787613925565b6003805460a860020a60ff0219169055979650505050505050565b61292f612ac8565b60085463ffffffff6401000000009091048116908216111561299b576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f434f4e56455253494f4e5f464545000000000000604482015290519081900360640190fd5b6008546040805163ffffffff6801000000000000000090930483168152918316602083015280517f81cd2ffb37dd237c0e4e2a3de5265fcf9deb43d3e7801e80db9f1ccfba7ee6009281900390910190a16008805463ffffffff90921668010000000000000000026bffffffff000000000000000019909216919091179055565b612a24612ac8565b600054600160a060020a0382811691161415612a8a576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f53414d455f4f574e4552000000000000000000000000000000000000604482015290519081900360640190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600454600160a060020a031690565b600054600160a060020a03163314610d08576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b600160a060020a0381166000908152600760205260409020600101546601000000000000900460ff161515610be0576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b612b8d612ac8565b610d086124ec565b60035460a860020a900460ff1615610d08576040805160e560020a62461bcd02815260206004820152600e60248201527f4552525f5245454e5452414e4359000000000000000000000000000000000000604482015290519081900360640190fd5b600080600080600080600080612c0b6135e8565b612c226000805160206148a9833981519152612ebc565b9750612c348a8a63ffffffff61362a16565b9650600095505b8b51861015612eae578b86815181101515612c5257fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935087600160a060020a0316638074590a8b86600860009054906101000a900463ffffffff168d6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b158015612d0857600080fd5b505af1158015612d1c573d6000803e3d6000fd5b505050506040513d6020811015612d3257600080fd5b50518b519093508b9087908110612d4557fe5b60209081029091010151831015612da6576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b612db6848463ffffffff61362a16565b600160a060020a03861660008181526007602052604090208290559092506000805160206148c98339815191521415612e1c57604051339084156108fc029085906000818181858888f19350505050158015612e16573d6000803e3d6000fd5b50612e27565b612e27853385613bf8565b60408051848152602081018490528082018990529051600160a060020a0387169133917fbc7d19d505c7ec4db83f3b51f19fb98c4c8a99922e7839d1ee608dfbee29501b9181900360600190a350600160a060020a03841660009081526007602052604090206001015463ffffffff16612ea3878684846137cf565b600190950194612c3b565b505050505050505050505050565b600254604080517fbb34534c000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a03169163bb34534c91602480830192602092919082900301818787803b158015612f2257600080fd5b505af1158015612f36573d6000803e3d6000fd5b505050506040513d6020811015612f4c57600080fd5b505192915050565b600160a060020a038116301415610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f414444524553535f49535f53454c4600000000000000000000000000604482015290519081900360640190fd5b612fbd612ac8565b82612fc78161318e565b82612fd18161318e565b83612fdb81612f54565b611496868686613bf8565b80612ff081612b18565b600160a060020a0382166000805160206148c9833981519152141561303057600160a060020a0382166000908152600760205260409020303190556130d7565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038416916370a082319160248083019260209291908290030181600087803b15801561309157600080fd5b505af11580156130a5573d6000803e3d6000fd5b505050506040513d60208110156130bb57600080fd5b5051600160a060020a0383166000908152600760205260409020555b5050565b6130e481612ebc565b600160a060020a03163314610be0576040805160e560020a62461bcd0281526020600482015260116024820152600080516020614909833981519152604482015290519081900360640190fd5b613139610be3565b15610d08576040805160e560020a62461bcd02815260206004820152600a60248201527f4552525f41435449564500000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0381161515610be0576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f494e56414c49445f4144445245535300000000000000000000000000604482015290519081900360640190fd5b60008163ffffffff1611801561320d5750620f424063ffffffff821611155b1515610be0576040805160e560020a62461bcd02815260206004820152601a60248201527f4552525f494e56414c49445f524553455256455f574549474854000000000000604482015290519081900360640190fd5b61326b610be3565b1515610d08576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f494e4143544956450000000000000000000000000000000000000000604482015290519081900360640190fd5b60065483516000918291811461330f576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b84518114613367576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b600092505b808310156135255760076000878581518110151561338657fe5b6020908102909101810151600160a060020a031682528101919091526040016000206001015460ff66010000000000009091041615156133fe576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600091505b8082101561346657858281518110151561341957fe5b90602001906020020151600160a060020a031660068481548110151561343b57fe5b600091825260209091200154600160a060020a0316141561345b57613466565b600190910190613403565b8082106134ab576040805160e560020a62461bcd0281526020600482015260136024820152600080516020614889833981519152604482015290519081900360640190fd5b600085848151811015156134bb57fe5b602090810290910101511161351a576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b60019092019161336c565b60008411611496576040805160e560020a62461bcd02815260206004820152600f60248201527f4552525f5a45524f5f414d4f554e540000000000000000000000000000000000604482015290519081900360640190fd5b6000811515613597576135908484613caf565b90506135a5565b6135a2848484613eb6565b90505b9392505050565b60085460009061268990620f4240906135dc90859063ffffffff6801000000000000000090910481169061427616565b9063ffffffff6142ef16565b60065460005b818110156130d75761362260068281548110151561360857fe5b600091825260209091200154600160a060020a0316612fe6565b6001016135ee565b600081831015613684576040805160e560020a62461bcd02815260206004820152600d60248201527f4552525f554e444552464c4f5700000000000000000000000000000000000000604482015290519081900360640190fd5b50900390565b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020808301919091528251918290036025018220600160a060020a038088166024850152861660448401526064808401869052845180850390910181526084909301909352810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff199093169290921790915261376c90859061435d565b50505050565b6000828201838110156135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600454600160a060020a0380851691167f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c2461380d85620f4240614276565b6138208863ffffffff8088169061427616565b6040805192835260208301919091528051918290030190a350505050565b613846612ac8565b6000613850611c35565b61ffff16116138a9576040805160e560020a62461bcd02815260206004820152601960248201527f4552525f494e56414c49445f524553455256455f434f554e5400000000000000604482015290519081900360640190fd5b60048054604080517f79ba50970000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216926379ba509792828201926000929082900301818387803b15801561390557600080fd5b505af1158015613919573d6000803e3d6000fd5b50505050610d086135e8565b600080600080613936898989611c91565b9093509150821515613992576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b61399b8861268f565b90508083106139a657fe5b600160a060020a0389166000805160206148c98339815191521415613a2157348714613a1c576040805160e560020a62461bcd02815260206004820152601760248201527f4552525f4554485f414d4f554e545f4d49534d41544348000000000000000000604482015290519081900360640190fd5b613b29565b34158015613ad3575086613ad0613a378b61268f565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038e16916370a082319160248083019260209291908290030181600087803b158015613a9857600080fd5b505af1158015613aac573d6000803e3d6000fd5b505050506040513d6020811015613ac257600080fd5b50519063ffffffff61362a16565b10155b1515613b29576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f494e56414c49445f414d4f554e540000000000000000000000000000604482015290519081900360640190fd5b613b3289612fe6565b600160a060020a038816600090815260076020526040902054613b5b908463ffffffff61362a16565b600160a060020a0389166000818152600760205260409020919091556000805160206148c98339815191521415613bc857604051600160a060020a0386169084156108fc029085906000818181858888f19350505050158015613bc2573d6000803e3d6000fd5b50613bd3565b613bd3888685613bf8565b613be18989888a87876143eb565b613beb8989614470565b5090979650505050505050565b604080517f7472616e7366657228616464726573732c75696e74323536290000000000000081528151908190036019018120600160a060020a038516602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1990931692909217909152613caa90849061435d565b505050565b600080600080613cbe85611c3b565b9250600091505b8551821015613eac5785516000805160206148c983398151915290879084908110613cec57fe5b60209081029091010151600160a060020a031614613d3e57613d3e8683815181101515613d1557fe5b9060200190602002015133308886815181101515613d2f57fe5b9060200190602002015161368a565b8482815181101515613d4c57fe5b90602001906020020151600760008885815181101515613d6857fe5b6020908102909101810151600160a060020a03168252810191909152604001600020558551869083908110613d9957fe5b90602001906020020151600160a060020a031633600160a060020a03167f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f78785815181101515613de557fe5b906020019060200201518886815181101515613dfd57fe5b60209081029091018101516040805193845291830152818101889052519081900360600190a3600760008784815181101515613e3557fe5b6020908102909101810151600160a060020a0316825281019190915260400160002060010154865163ffffffff9091169150613ea1908490889085908110613e7957fe5b906020019060200201518785815181101515613e9157fe5b90602001906020020151846137cf565b600190910190613cc5565b5090949350505050565b600080600080600080600080600080613ecd6135e8565b6000805160206148c9833981519152600052600760205260008051602061492983398151915254613f04903463ffffffff61362a16565b6000805160206148c9833981519152600052600760205260008051602061492983398151915255613f426000805160206148a9833981519152612ebc565b9850613f50898c8f8f61467e565b9750613f628b8963ffffffff61377216565b9650600095505b8c51861015614265578c86815181101515613f8057fe5b9060200190602002015194506007600086600160a060020a0316600160a060020a0316815260200190815260200160002060000154935088600160a060020a031663ebbb21588c86600860009054906101000a900463ffffffff168c6040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561403657600080fd5b505af115801561404a573d6000803e3d6000fd5b505050506040513d602081101561406057600080fd5b50519250600083116140bc576040805160e560020a62461bcd02815260206004820152601660248201527f4552525f5a45524f5f5441524745545f414d4f554e5400000000000000000000604482015290519081900360640190fd5b8b868151811015156140ca57fe5b602090810290910101518311156140dd57fe5b600160a060020a0385166000805160206148c98339815191521461410c576141078533308661368a565b61417f565b828c8781518110151561411b57fe5b90602001906020020151111561417f5733600160a060020a03166108fc848e8981518110151561414757fe5b90602001906020020151039081150290604051600060405180830381858888f1935050505015801561417d573d6000803e3d6000fd5b505b61418f848463ffffffff61377216565b600160a060020a03861660008181526007602090815260409182902084905581518781529081018490528082018b90529051929450909133917f4a1a2a6176e9646d9e3157f7c2ab3c499f18337c0b0828cfb28e0a61de4a11f7919081900360600190a3600760008e8881518110151561420557fe5b6020908102909101810151600160a060020a03168252810191909152604001600020600101548d5163ffffffff909116915061425a9088908f908990811061424957fe5b9060200190602002015184846137cf565b600190950194613f69565b50959b9a5050505050505050505050565b600080831515614289576000915061181c565b5082820282848281151561429957fe5b04146135a5576040805160e560020a62461bcd02815260206004820152600c60248201527f4552525f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b600080808311614349576040805160e560020a62461bcd02815260206004820152601260248201527f4552525f4449564944455f42595f5a45524f0000000000000000000000000000604482015290519081900360640190fd5b828481151561435457fe5b04949350505050565b614365614869565b602060405190810160405280600181525090506020818351602085016000875af180151561439257600080fd5b5080511515613caa576040805160e560020a62461bcd02815260206004820152601360248201527f4552525f5452414e534645525f4641494c454400000000000000000000000000604482015290519081900360640190fd5b7f8000000000000000000000000000000000000000000000000000000000000000811061441457fe5b60408051848152602081018490528082018390529051600160a060020a038087169288821692918a16917f276856b36cbc45526a0ba64f44611557a2a8b68662c5388e9fe6d72e86e1c8cb9181900360600190a4505050505050565b6000806000806000806000600460009054906101000a9004600160a060020a0316600160a060020a03166318160ddd6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156144ce57600080fd5b505af11580156144e2573d6000803e3d6000fd5b505050506040513d60208110156144f857600080fd5b505196506145058961268f565b95506145108861268f565b600160a060020a03808b16600090815260076020526040808220600190810154938d1683529120015491965063ffffffff90811695509081169350614559908690869061427616565b915061456e8663ffffffff8086169061427616565b60408051848152602081018390528151929350600160a060020a03808c1693908d16927f77f29993cf2c084e726f7e802da0719d6a0ade3e204badc7a3ffd57ecb768c24928290030190a36145c5878a88876137cf565b6145d1878987866137cf565b604080518881526020810188905263ffffffff8616818301529051600160a060020a038b16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2604080518881526020810187905263ffffffff8516818301529051600160a060020a038a16917f8a6a7f53b3c8fa1dc4b83e3f1be668c1b251ff8d44cdcb83eb3acec3fec6a788919081900360600190a2505050505050505050565b60008060015b8451811015614741576146e96007600087848151811015156146a257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205485518690859081106146d357fe5b602090810290910101519063ffffffff61427616565b61472f6007600088868151811015156146fe57fe5b6020908102909101810151600160a060020a031682528101919091526040016000205486518790859081106146d357fe5b1015614739578091505b600101614684565b86600160a060020a0316632f55bdb58760076000898781518110151561476357fe5b6020908102909101810151600160a060020a0316825281019190915260400160002054600854885163ffffffff909116908990889081106147a057fe5b906020019060200201516040518563ffffffff1660e060020a028152600401808581526020018481526020018363ffffffff1663ffffffff168152602001828152602001945050505050602060405180830381600087803b15801561480457600080fd5b505af1158015614818573d6000803e3d6000fd5b505050506040513d602081101561482e57600080fd5b5051979650505050505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b602060405190810160405280600190602082028038833950919291505056004552525f494e56414c49445f524553455256450000000000000000000000000042616e636f72466f726d756c6100000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee42616e636f72436f6e76657274657255706772616465720000000000000000004552525f4143434553535f44454e494544000000000000000000000000000000b2084a3e4595ccf007fb44245853374aaf0de960074375e8e0fb334712e94d0ea165627a7a723058208ac6a9739e89dc82908965c8f0959f549da7cb06de5a581cb9b21b2afd9ede1d0029

Verified Source Code Partial Match

Compiler: v0.4.26+commit.4563c3fc EVM: byzantium Optimization: Yes (200 runs)
LiquidityPoolV1Converter.sol 2008 lines
// File: contracts/utility/interfaces/IOwned.sol

pragma solidity 0.4.26;

/*
    Owned contract interface
*/
contract IOwned {
    // this function isn't abstract since the compiler emits automatically generated getter functions as external
    function owner() public view returns (address) {this;}

    function transferOwnership(address _newOwner) public;
    function acceptOwnership() public;
}

// File: contracts/token/interfaces/IERC20Token.sol

pragma solidity 0.4.26;

/*
    ERC20 Standard Token interface
*/
contract IERC20Token {
    // these functions aren't abstract since the compiler emits automatically generated getter functions as external
    function name() public view returns (string) {this;}
    function symbol() public view returns (string) {this;}
    function decimals() public view returns (uint8) {this;}
    function totalSupply() public view returns (uint256) {this;}
    function balanceOf(address _owner) public view returns (uint256) {_owner; this;}
    function allowance(address _owner, address _spender) public view returns (uint256) {_owner; _spender; this;}

    function transfer(address _to, uint256 _value) public returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    function approve(address _spender, uint256 _value) public returns (bool success);
}

// File: contracts/utility/interfaces/ITokenHolder.sol

pragma solidity 0.4.26;



/*
    Token Holder interface
*/
contract ITokenHolder is IOwned {
    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public;
}

// File: contracts/converter/interfaces/IConverterAnchor.sol

pragma solidity 0.4.26;



/*
    Converter Anchor interface
*/
contract IConverterAnchor is IOwned, ITokenHolder {
}

// File: contracts/utility/interfaces/IWhitelist.sol

pragma solidity 0.4.26;

/*
    Whitelist interface
*/
contract IWhitelist {
    function isWhitelisted(address _address) public view returns (bool);
}

// File: contracts/converter/interfaces/IConverter.sol

pragma solidity 0.4.26;





/*
    Converter interface
*/
contract IConverter is IOwned {
    function converterType() public pure returns (uint16);
    function anchor() public view returns (IConverterAnchor) {this;}
    function isActive() public view returns (bool);

    function targetAmountAndFee(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount) public view returns (uint256, uint256);
    function convert(IERC20Token _sourceToken,
                     IERC20Token _targetToken,
                     uint256 _amount,
                     address _trader,
                     address _beneficiary) public payable returns (uint256);

    function conversionWhitelist() public view returns (IWhitelist) {this;}
    function conversionFee() public view returns (uint32) {this;}
    function maxConversionFee() public view returns (uint32) {this;}
    function reserveBalance(IERC20Token _reserveToken) public view returns (uint256);
    function() external payable;

    function transferAnchorOwnership(address _newOwner) public;
    function acceptAnchorOwnership() public;
    function setConversionFee(uint32 _conversionFee) public;
    function setConversionWhitelist(IWhitelist _whitelist) public;
    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public;
    function withdrawETH(address _to) public;
    function addReserve(IERC20Token _token, uint32 _ratio) public;

    // deprecated, backward compatibility
    function token() public view returns (IConverterAnchor);
    function transferTokenOwnership(address _newOwner) public;
    function acceptTokenOwnership() public;
    function connectors(address _address) public view returns (uint256, uint32, bool, bool, bool);
    function getConnectorBalance(IERC20Token _connectorToken) public view returns (uint256);
    function connectorTokens(uint256 _index) public view returns (IERC20Token);
    function connectorTokenCount() public view returns (uint16);
}

// File: contracts/converter/interfaces/IConverterUpgrader.sol

pragma solidity 0.4.26;

/*
    Converter Upgrader interface
*/
contract IConverterUpgrader {
    function upgrade(bytes32 _version) public;
    function upgrade(uint16 _version) public;
}

// File: contracts/converter/interfaces/IBancorFormula.sol

pragma solidity 0.4.26;

/*
    Bancor Formula interface
*/
contract IBancorFormula {
    function purchaseTargetAmount(uint256 _supply,
                                  uint256 _reserveBalance,
                                  uint32 _reserveWeight,
                                  uint256 _amount)
                                  public view returns (uint256);

    function saleTargetAmount(uint256 _supply,
                              uint256 _reserveBalance,
                              uint32 _reserveWeight,
                              uint256 _amount)
                              public view returns (uint256);

    function crossReserveTargetAmount(uint256 _sourceReserveBalance,
                                      uint32 _sourceReserveWeight,
                                      uint256 _targetReserveBalance,
                                      uint32 _targetReserveWeight,
                                      uint256 _amount)
                                      public view returns (uint256);

    function fundCost(uint256 _supply,
                      uint256 _reserveBalance,
                      uint32 _reserveRatio,
                      uint256 _amount)
                      public view returns (uint256);

    function fundSupplyAmount(uint256 _supply,
                              uint256 _reserveBalance,
                              uint32 _reserveRatio,
                              uint256 _amount)
                              public view returns (uint256);

    function liquidateReserveAmount(uint256 _supply,
                                    uint256 _reserveBalance,
                                    uint32 _reserveRatio,
                                    uint256 _amount)
                                    public view returns (uint256);
}

// File: contracts/IBancorNetwork.sol

pragma solidity 0.4.26;


/*
    Bancor Network interface
*/
contract IBancorNetwork {
    function convert2(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _affiliateAccount,
        uint256 _affiliateFee
    ) public payable returns (uint256);

    function claimAndConvert2(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _affiliateAccount,
        uint256 _affiliateFee
    ) public returns (uint256);

    function convertFor2(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _for,
        address _affiliateAccount,
        uint256 _affiliateFee
    ) public payable returns (uint256);

    function claimAndConvertFor2(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _for,
        address _affiliateAccount,
        uint256 _affiliateFee
    ) public returns (uint256);

    // deprecated, backward compatibility
    function convert(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn
    ) public payable returns (uint256);

    // deprecated, backward compatibility
    function claimAndConvert(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn
    ) public returns (uint256);

    // deprecated, backward compatibility
    function convertFor(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _for
    ) public payable returns (uint256);

    // deprecated, backward compatibility
    function claimAndConvertFor(
        IERC20Token[] _path,
        uint256 _amount,
        uint256 _minReturn,
        address _for
    ) public returns (uint256);
}

// File: contracts/utility/Owned.sol

pragma solidity 0.4.26;


/**
  * @dev Provides support and utilities for contract ownership
*/
contract Owned is IOwned {
    address public owner;
    address public newOwner;

    /**
      * @dev triggered when the owner is updated
      *
      * @param _prevOwner previous owner
      * @param _newOwner  new owner
    */
    event OwnerUpdate(address indexed _prevOwner, address indexed _newOwner);

    /**
      * @dev initializes a new Owned instance
    */
    constructor() public {
        owner = msg.sender;
    }

    // allows execution by the owner only
    modifier ownerOnly {
        _ownerOnly();
        _;
    }

    // error message binary size optimization
    function _ownerOnly() internal view {
        require(msg.sender == owner, "ERR_ACCESS_DENIED");
    }

    /**
      * @dev allows transferring the contract ownership
      * the new owner still needs to accept the transfer
      * can only be called by the contract owner
      *
      * @param _newOwner    new contract owner
    */
    function transferOwnership(address _newOwner) public ownerOnly {
        require(_newOwner != owner, "ERR_SAME_OWNER");
        newOwner = _newOwner;
    }

    /**
      * @dev used by a new owner to accept an ownership transfer
    */
    function acceptOwnership() public {
        require(msg.sender == newOwner, "ERR_ACCESS_DENIED");
        emit OwnerUpdate(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}

// File: contracts/utility/Utils.sol

pragma solidity 0.4.26;

/**
  * @dev Utilities & Common Modifiers
*/
contract Utils {
    // verifies that a value is greater than zero
    modifier greaterThanZero(uint256 _value) {
        _greaterThanZero(_value);
        _;
    }

    // error message binary size optimization
    function _greaterThanZero(uint256 _value) internal pure {
        require(_value > 0, "ERR_ZERO_VALUE");
    }

    // validates an address - currently only checks that it isn't null
    modifier validAddress(address _address) {
        _validAddress(_address);
        _;
    }

    // error message binary size optimization
    function _validAddress(address _address) internal pure {
        require(_address != address(0), "ERR_INVALID_ADDRESS");
    }

    // verifies that the address is different than this contract address
    modifier notThis(address _address) {
        _notThis(_address);
        _;
    }

    // error message binary size optimization
    function _notThis(address _address) internal view {
        require(_address != address(this), "ERR_ADDRESS_IS_SELF");
    }
}

// File: contracts/utility/interfaces/IContractRegistry.sol

pragma solidity 0.4.26;

/*
    Contract Registry interface
*/
contract IContractRegistry {
    function addressOf(bytes32 _contractName) public view returns (address);

    // deprecated, backward compatibility
    function getAddress(bytes32 _contractName) public view returns (address);
}

// File: contracts/utility/ContractRegistryClient.sol

pragma solidity 0.4.26;




/**
  * @dev Base contract for ContractRegistry clients
*/
contract ContractRegistryClient is Owned, Utils {
    bytes32 internal constant CONTRACT_REGISTRY = "ContractRegistry";
    bytes32 internal constant BANCOR_NETWORK = "BancorNetwork";
    bytes32 internal constant BANCOR_FORMULA = "BancorFormula";
    bytes32 internal constant CONVERTER_FACTORY = "ConverterFactory";
    bytes32 internal constant CONVERSION_PATH_FINDER = "ConversionPathFinder";
    bytes32 internal constant CONVERTER_UPGRADER = "BancorConverterUpgrader";
    bytes32 internal constant CONVERTER_REGISTRY = "BancorConverterRegistry";
    bytes32 internal constant CONVERTER_REGISTRY_DATA = "BancorConverterRegistryData";
    bytes32 internal constant BNT_TOKEN = "BNTToken";
    bytes32 internal constant BANCOR_X = "BancorX";
    bytes32 internal constant BANCOR_X_UPGRADER = "BancorXUpgrader";

    IContractRegistry public registry;      // address of the current contract-registry
    IContractRegistry public prevRegistry;  // address of the previous contract-registry
    bool public onlyOwnerCanUpdateRegistry; // only an owner can update the contract-registry

    /**
      * @dev verifies that the caller is mapped to the given contract name
      *
      * @param _contractName    contract name
    */
    modifier only(bytes32 _contractName) {
        _only(_contractName);
        _;
    }

    // error message binary size optimization
    function _only(bytes32 _contractName) internal view {
        require(msg.sender == addressOf(_contractName), "ERR_ACCESS_DENIED");
    }

    /**
      * @dev initializes a new ContractRegistryClient instance
      *
      * @param  _registry   address of a contract-registry contract
    */
    constructor(IContractRegistry _registry) internal validAddress(_registry) {
        registry = IContractRegistry(_registry);
        prevRegistry = IContractRegistry(_registry);
    }

    /**
      * @dev updates to the new contract-registry
     */
    function updateRegistry() public {
        // verify that this function is permitted
        require(msg.sender == owner || !onlyOwnerCanUpdateRegistry, "ERR_ACCESS_DENIED");

        // get the new contract-registry
        IContractRegistry newRegistry = IContractRegistry(addressOf(CONTRACT_REGISTRY));

        // verify that the new contract-registry is different and not zero
        require(newRegistry != address(registry) && newRegistry != address(0), "ERR_INVALID_REGISTRY");

        // verify that the new contract-registry is pointing to a non-zero contract-registry
        require(newRegistry.addressOf(CONTRACT_REGISTRY) != address(0), "ERR_INVALID_REGISTRY");

        // save a backup of the current contract-registry before replacing it
        prevRegistry = registry;

        // replace the current contract-registry with the new contract-registry
        registry = newRegistry;
    }

    /**
      * @dev restores the previous contract-registry
    */
    function restoreRegistry() public ownerOnly {
        // restore the previous contract-registry
        registry = prevRegistry;
    }

    /**
      * @dev restricts the permission to update the contract-registry
      *
      * @param _onlyOwnerCanUpdateRegistry  indicates whether or not permission is restricted to owner only
    */
    function restrictRegistryUpdate(bool _onlyOwnerCanUpdateRegistry) public ownerOnly {
        // change the permission to update the contract-registry
        onlyOwnerCanUpdateRegistry = _onlyOwnerCanUpdateRegistry;
    }

    /**
      * @dev returns the address associated with the given contract name
      *
      * @param _contractName    contract name
      *
      * @return contract address
    */
    function addressOf(bytes32 _contractName) internal view returns (address) {
        return registry.addressOf(_contractName);
    }
}

// File: contracts/utility/ReentrancyGuard.sol

pragma solidity 0.4.26;

/**
  * @dev ReentrancyGuard
  *
  * The contract provides protection against re-entrancy - calling a function (directly or
  * indirectly) from within itself.
*/
contract ReentrancyGuard {
    // true while protected code is being executed, false otherwise
    bool private locked = false;

    /**
      * @dev ensures instantiation only by sub-contracts
    */
    constructor() internal {}

    // protects a function against reentrancy attacks
    modifier protected() {
        _protected();
        locked = true;
        _;
        locked = false;
    }

    // error message binary size optimization
    function _protected() internal view {
        require(!locked, "ERR_REENTRANCY");
    }
}

// File: contracts/utility/SafeMath.sol

pragma solidity 0.4.26;

/**
  * @dev Library for basic math operations with overflow/underflow protection
*/
library SafeMath {
    /**
      * @dev returns the sum of _x and _y, reverts if the calculation overflows
      *
      * @param _x   value 1
      * @param _y   value 2
      *
      * @return sum
    */
    function add(uint256 _x, uint256 _y) internal pure returns (uint256) {
        uint256 z = _x + _y;
        require(z >= _x, "ERR_OVERFLOW");
        return z;
    }

    /**
      * @dev returns the difference of _x minus _y, reverts if the calculation underflows
      *
      * @param _x   minuend
      * @param _y   subtrahend
      *
      * @return difference
    */
    function sub(uint256 _x, uint256 _y) internal pure returns (uint256) {
        require(_x >= _y, "ERR_UNDERFLOW");
        return _x - _y;
    }

    /**
      * @dev returns the product of multiplying _x by _y, reverts if the calculation overflows
      *
      * @param _x   factor 1
      * @param _y   factor 2
      *
      * @return product
    */
    function mul(uint256 _x, uint256 _y) internal pure returns (uint256) {
        // gas optimization
        if (_x == 0)
            return 0;

        uint256 z = _x * _y;
        require(z / _x == _y, "ERR_OVERFLOW");
        return z;
    }

    /**
      * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
      *
      * @param _x   dividend
      * @param _y   divisor
      *
      * @return quotient
    */
    function div(uint256 _x, uint256 _y) internal pure returns (uint256) {
        require(_y > 0, "ERR_DIVIDE_BY_ZERO");
        uint256 c = _x / _y;
        return c;
    }
}

// File: contracts/utility/TokenHandler.sol

pragma solidity 0.4.26;


contract TokenHandler {
    bytes4 private constant APPROVE_FUNC_SELECTOR = bytes4(keccak256("approve(address,uint256)"));
    bytes4 private constant TRANSFER_FUNC_SELECTOR = bytes4(keccak256("transfer(address,uint256)"));
    bytes4 private constant TRANSFER_FROM_FUNC_SELECTOR = bytes4(keccak256("transferFrom(address,address,uint256)"));

    /**
      * @dev executes the ERC20 token's `approve` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _spender approved address
      * @param _value   allowance amount
    */
    function safeApprove(IERC20Token _token, address _spender, uint256 _value) internal {
       execute(_token, abi.encodeWithSelector(APPROVE_FUNC_SELECTOR, _spender, _value));
    }

    /**
      * @dev executes the ERC20 token's `transfer` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _to      target address
      * @param _value   transfer amount
    */
    function safeTransfer(IERC20Token _token, address _to, uint256 _value) internal {
       execute(_token, abi.encodeWithSelector(TRANSFER_FUNC_SELECTOR, _to, _value));
    }

    /**
      * @dev executes the ERC20 token's `transferFrom` function and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _from    source address
      * @param _to      target address
      * @param _value   transfer amount
    */
    function safeTransferFrom(IERC20Token _token, address _from, address _to, uint256 _value) internal {
       execute(_token, abi.encodeWithSelector(TRANSFER_FROM_FUNC_SELECTOR, _from, _to, _value));
    }

    /**
      * @dev executes a function on the ERC20 token and reverts upon failure
      * the main purpose of this function is to prevent a non standard ERC20 token
      * from failing silently
      *
      * @param _token   ERC20 token address
      * @param _data    data to pass in to the token's contract for execution
    */
    function execute(IERC20Token _token, bytes memory _data) private {
        uint256[1] memory ret = [uint256(1)];

        assembly {
            let success := call(
                gas,            // gas remaining
                _token,         // destination address
                0,              // no ether
                add(_data, 32), // input buffer (starts after the first 32 bytes in the `data` array)
                mload(_data),   // input length (loaded from the first 32 bytes in the `data` array)
                ret,            // output buffer
                32              // output length
            )
            if iszero(success) {
                revert(0, 0)
            }
        }

        require(ret[0] != 0, "ERR_TRANSFER_FAILED");
    }
}

// File: contracts/utility/TokenHolder.sol

pragma solidity 0.4.26;






/**
  * @dev We consider every contract to be a 'token holder' since it's currently not possible
  * for a contract to deny receiving tokens.
  *
  * The TokenHolder's contract sole purpose is to provide a safety mechanism that allows
  * the owner to send tokens that were sent to the contract by mistake back to their sender.
  *
  * Note that we use the non standard ERC-20 interface which has no return value for transfer
  * in order to support both non standard as well as standard token contracts.
  * see https://github.com/ethereum/solidity/issues/4116
*/
contract TokenHolder is ITokenHolder, TokenHandler, Owned, Utils {
    /**
      * @dev withdraws tokens held by the contract and sends them to an account
      * can only be called by the owner
      *
      * @param _token   ERC20 token contract address
      * @param _to      account to receive the new amount
      * @param _amount  amount to withdraw
    */
    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount)
        public
        ownerOnly
        validAddress(_token)
        validAddress(_to)
        notThis(_to)
    {
        safeTransfer(_token, _to, _amount);
    }
}

// File: contracts/token/interfaces/IEtherToken.sol

pragma solidity 0.4.26;


/*
    Ether Token interface
*/
contract IEtherToken is IERC20Token {
    function deposit() public payable;
    function withdraw(uint256 _amount) public;
    function depositTo(address _to) public payable;
    function withdrawTo(address _to, uint256 _amount) public;
}

// File: contracts/bancorx/interfaces/IBancorX.sol

pragma solidity 0.4.26;


contract IBancorX {
    function token() public view returns (IERC20Token) {this;}
    function xTransfer(bytes32 _toBlockchain, bytes32 _to, uint256 _amount, uint256 _id) public;
    function getXTransferAmount(uint256 _xTransferId, address _for) public view returns (uint256);
}

// File: contracts/converter/ConverterBase.sol

pragma solidity 0.4.26;













/**
  * @dev ConverterBase
  *
  * The converter contains the main logic for conversions between different ERC20 tokens.
  *
  * It is also the upgradable part of the mechanism (note that upgrades are opt-in).
  *
  * The anchor must be set on construction and cannot be changed afterwards.
  * Wrappers are provided for some of the anchor's functions, for easier access.
  *
  * Once the converter accepts ownership of the anchor, it becomes the anchor's sole controller
  * and can execute any of its functions.
  *
  * To upgrade the converter, anchor ownership must be transferred to a new converter, along with
  * any relevant data.
  *
  * Note that the converter can transfer anchor ownership to a new converter that
  * doesn't allow upgrades anymore, for finalizing the relationship between the converter
  * and the anchor.
  *
  * Converter types (defined as uint16 type) -
  * 0 = liquid token converter
  * 1 = liquidity pool v1 converter
  * 2 = liquidity pool v2 converter
  *
  * Note that converters don't currently support tokens with transfer fees.
*/
contract ConverterBase is IConverter, TokenHandler, TokenHolder, ContractRegistryClient, ReentrancyGuard {
    using SafeMath for uint256;

    uint32 internal constant WEIGHT_RESOLUTION = 1000000;
    uint64 internal constant CONVERSION_FEE_RESOLUTION = 1000000;
    address internal constant ETH_RESERVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    struct Reserve {
        uint256 balance;    // reserve balance
        uint32 weight;      // reserve weight, represented in ppm, 1-1000000
        bool deprecated1;   // deprecated
        bool deprecated2;   // deprecated
        bool isSet;         // true if the reserve is valid, false otherwise
    }

    /**
      * @dev version number
    */
    uint16 public constant version = 30;

    IConverterAnchor public anchor;                 // converter anchor contract
    IWhitelist public conversionWhitelist;          // whitelist contract with list of addresses that are allowed to use the converter
    IERC20Token[] public reserveTokens;             // ERC20 standard token addresses (prior version 17, use 'connectorTokens' instead)
    mapping (address => Reserve) public reserves;   // reserve token addresses -> reserve data (prior version 17, use 'connectors' instead)
    uint32 public reserveRatio = 0;                 // ratio between the reserves and the market cap, equal to the total reserve weights
    uint32 public maxConversionFee = 0;             // maximum conversion fee for the lifetime of the contract,
                                                    // represented in ppm, 0...1000000 (0 = no fee, 100 = 0.01%, 1000000 = 100%)
    uint32 public conversionFee = 0;                // current conversion fee, represented in ppm, 0...maxConversionFee
    bool public constant conversionsEnabled = true; // deprecated, backward compatibility

    /**
      * @dev triggered when the converter is activated
      *
      * @param _anchor      converter anchor
      * @param _activated   true if the converter was activated, false if it was deactivated
    */
    event Activation(IConverterAnchor _anchor, bool _activated);

    /**
      * @dev triggered when a conversion between two tokens occurs
      *
      * @param _fromToken       source ERC20 token
      * @param _toToken         target ERC20 token
      * @param _trader          wallet that initiated the trade
      * @param _amount          amount converted, in the source token
      * @param _return          amount returned, minus conversion fee
      * @param _conversionFee   conversion fee
    */
    event Conversion(
        address indexed _fromToken,
        address indexed _toToken,
        address indexed _trader,
        uint256 _amount,
        uint256 _return,
        int256 _conversionFee
    );

    /**
      * @dev triggered when the rate between two tokens in the converter changes
      * note that the event might be dispatched for rate updates between any two tokens in the converter
      * note that prior to version 28, you should use the 'PriceDataUpdate' event instead
      *
      * @param  _token1 address of the first token
      * @param  _token2 address of the second token
      * @param  _rateN  rate of 1 unit of `_token1` in `_token2` (numerator)
      * @param  _rateD  rate of 1 unit of `_token1` in `_token2` (denominator)
    */
    event TokenRateUpdate(
        address indexed _token1,
        address indexed _token2,
        uint256 _rateN,
        uint256 _rateD
    );

    /**
      * @dev triggered when the conversion fee is updated
      *
      * @param  _prevFee    previous fee percentage, represented in ppm
      * @param  _newFee     new fee percentage, represented in ppm
    */
    event ConversionFeeUpdate(uint32 _prevFee, uint32 _newFee);

    /**
      * @dev used by sub-contracts to initialize a new converter
      *
      * @param  _anchor             anchor governed by the converter
      * @param  _registry           address of a contract registry contract
      * @param  _maxConversionFee   maximum conversion fee, represented in ppm
    */
    constructor(
        IConverterAnchor _anchor,
        IContractRegistry _registry,
        uint32 _maxConversionFee
    )
        validAddress(_anchor)
        ContractRegistryClient(_registry)
        internal
        validConversionFee(_maxConversionFee)
    {
        anchor = _anchor;
        maxConversionFee = _maxConversionFee;
    }

    // ensures that the converter is active
    modifier active() {
        _active();
        _;
    }

    // error message binary size optimization
    function _active() internal view {
        require(isActive(), "ERR_INACTIVE");
    }

    // ensures that the converter is not active
    modifier inactive() {
        _inactive();
        _;
    }

    // error message binary size optimization
    function _inactive() internal view {
        require(!isActive(), "ERR_ACTIVE");
    }

    // validates a reserve token address - verifies that the address belongs to one of the reserve tokens
    modifier validReserve(IERC20Token _address) {
        _validReserve(_address);
        _;
    }

    // error message binary size optimization
    function _validReserve(IERC20Token _address) internal view {
        require(reserves[_address].isSet, "ERR_INVALID_RESERVE");
    }

    // validates conversion fee
    modifier validConversionFee(uint32 _conversionFee) {
        _validConversionFee(_conversionFee);
        _;
    }

    // error message binary size optimization
    function _validConversionFee(uint32 _conversionFee) internal pure {
        require(_conversionFee <= CONVERSION_FEE_RESOLUTION, "ERR_INVALID_CONVERSION_FEE");
    }

    // validates reserve weight
    modifier validReserveWeight(uint32 _weight) {
        _validReserveWeight(_weight);
        _;
    }

    // error message binary size optimization
    function _validReserveWeight(uint32 _weight) internal pure {
        require(_weight > 0 && _weight <= WEIGHT_RESOLUTION, "ERR_INVALID_RESERVE_WEIGHT");
    }

    /**
      * @dev deposits ether
      * can only be called if the converter has an ETH reserve
    */
    function() external payable {
        require(reserves[ETH_RESERVE_ADDRESS].isSet, "ERR_INVALID_RESERVE"); // require(hasETHReserve(), "ERR_INVALID_RESERVE");
        // a workaround for a problem when running solidity-coverage
        // see https://github.com/sc-forks/solidity-coverage/issues/487
    }

    /**
      * @dev withdraws ether
      * can only be called by the owner if the converter is inactive or by upgrader contract
      * can only be called after the upgrader contract has accepted the ownership of this contract
      * can only be called if the converter has an ETH reserve
      *
      * @param _to  address to send the ETH to
    */
    function withdrawETH(address _to)
        public
        protected
        ownerOnly
        validReserve(IERC20Token(ETH_RESERVE_ADDRESS))
    {
        address converterUpgrader = addressOf(CONVERTER_UPGRADER);

        // verify that the converter is inactive or that the owner is the upgrader contract
        require(!isActive() || owner == converterUpgrader, "ERR_ACCESS_DENIED");
        _to.transfer(address(this).balance);

        // sync the ETH reserve balance
        syncReserveBalance(IERC20Token(ETH_RESERVE_ADDRESS));
    }

    /**
      * @dev checks whether or not the converter version is 28 or higher
      *
      * @return true, since the converter version is 28 or higher
    */
    function isV28OrHigher() public pure returns (bool) {
        return true;
    }

    /**
      * @dev allows the owner to update & enable the conversion whitelist contract address
      * when set, only addresses that are whitelisted are actually allowed to use the converter
      * note that the whitelist check is actually done by the BancorNetwork contract
      *
      * @param _whitelist    address of a whitelist contract
    */
    function setConversionWhitelist(IWhitelist _whitelist)
        public
        ownerOnly
        notThis(_whitelist)
    {
        conversionWhitelist = _whitelist;
    }

    /**
      * @dev returns true if the converter is active, false otherwise
    */
    function isActive() public view returns (bool) {
        return anchor.owner() == address(this);
    }

    /**
      * @dev transfers the anchor ownership
      * the new owner needs to accept the transfer
      * can only be called by the converter upgrder while the upgrader is the owner
      * note that prior to version 28, you should use 'transferAnchorOwnership' instead
      *
      * @param _newOwner    new token owner
    */
    function transferAnchorOwnership(address _newOwner)
        public
        ownerOnly
        only(CONVERTER_UPGRADER)
    {
        anchor.transferOwnership(_newOwner);
    }

    /**
      * @dev accepts ownership of the anchor after an ownership transfer
      * most converters are also activated as soon as they accept the anchor ownership
      * can only be called by the contract owner
      * note that prior to version 28, you should use 'acceptTokenOwnership' instead
    */
    function acceptAnchorOwnership() public ownerOnly {
        // verify the the converter has at least one reserve
        require(reserveTokenCount() > 0, "ERR_INVALID_RESERVE_COUNT");
        anchor.acceptOwnership();
        syncReserveBalances();
    }

    /**
      * @dev withdraws tokens held by the anchor and sends them to an account
      * can only be called by the owner
      *
      * @param _token   ERC20 token contract address
      * @param _to      account to receive the new amount
      * @param _amount  amount to withdraw
    */
    function withdrawFromAnchor(IERC20Token _token, address _to, uint256 _amount) public ownerOnly {
        anchor.withdrawTokens(_token, _to, _amount);
    }

    /**
      * @dev updates the current conversion fee
      * can only be called by the contract owner
      *
      * @param _conversionFee new conversion fee, represented in ppm
    */
    function setConversionFee(uint32 _conversionFee) public ownerOnly {
        require(_conversionFee <= maxConversionFee, "ERR_INVALID_CONVERSION_FEE");
        emit ConversionFeeUpdate(conversionFee, _conversionFee);
        conversionFee = _conversionFee;
    }

    /**
      * @dev withdraws tokens held by the converter and sends them to an account
      * can only be called by the owner
      * note that reserve tokens can only be withdrawn by the owner while the converter is inactive
      * unless the owner is the converter upgrader contract
      *
      * @param _token   ERC20 token contract address
      * @param _to      account to receive the new amount
      * @param _amount  amount to withdraw
    */
    function withdrawTokens(IERC20Token _token, address _to, uint256 _amount) public protected ownerOnly {
        address converterUpgrader = addressOf(CONVERTER_UPGRADER);

        // if the token is not a reserve token, allow withdrawal
        // otherwise verify that the converter is inactive or that the owner is the upgrader contract
        require(!reserves[_token].isSet || !isActive() || owner == converterUpgrader, "ERR_ACCESS_DENIED");
        super.withdrawTokens(_token, _to, _amount);

        // if the token is a reserve token, sync the reserve balance
        if (reserves[_token].isSet)
            syncReserveBalance(_token);
    }

    /**
      * @dev upgrades the converter to the latest version
      * can only be called by the owner
      * note that the owner needs to call acceptOwnership on the new converter after the upgrade
    */
    function upgrade() public ownerOnly {
        IConverterUpgrader converterUpgrader = IConverterUpgrader(addressOf(CONVERTER_UPGRADER));

        transferOwnership(converterUpgrader);
        converterUpgrader.upgrade(version);
        acceptOwnership();
    }

    /**
      * @dev returns the number of reserve tokens defined
      * note that prior to version 17, you should use 'connectorTokenCount' instead
      *
      * @return number of reserve tokens
    */
    function reserveTokenCount() public view returns (uint16) {
        return uint16(reserveTokens.length);
    }

    /**
      * @dev defines a new reserve token for the converter
      * can only be called by the owner while the converter is inactive
      *
      * @param _token   address of the reserve token
      * @param _weight  reserve weight, represented in ppm, 1-1000000
    */
    function addReserve(IERC20Token _token, uint32 _weight)
        public
        ownerOnly
        inactive
        validAddress(_token)
        notThis(_token)
        validReserveWeight(_weight)
    {
        // validate input
        require(_token != address(anchor) && !reserves[_token].isSet, "ERR_INVALID_RESERVE");
        require(_weight <= WEIGHT_RESOLUTION - reserveRatio, "ERR_INVALID_RESERVE_WEIGHT");
        require(reserveTokenCount() < uint16(-1), "ERR_INVALID_RESERVE_COUNT");

        Reserve storage newReserve = reserves[_token];
        newReserve.balance = 0;
        newReserve.weight = _weight;
        newReserve.isSet = true;
        reserveTokens.push(_token);
        reserveRatio += _weight;
    }

    /**
      * @dev returns the reserve's weight
      * added in version 28
      *
      * @param _reserveToken    reserve token contract address
      *
      * @return reserve weight
    */
    function reserveWeight(IERC20Token _reserveToken)
        public
        view
        validReserve(_reserveToken)
        returns (uint32)
    {
        return reserves[_reserveToken].weight;
    }

    /**
      * @dev returns the reserve's balance
      * note that prior to version 17, you should use 'getConnectorBalance' instead
      *
      * @param _reserveToken    reserve token contract address
      *
      * @return reserve balance
    */
    function reserveBalance(IERC20Token _reserveToken)
        public
        view
        validReserve(_reserveToken)
        returns (uint256)
    {
        return reserves[_reserveToken].balance;
    }

    /**
      * @dev checks whether or not the converter has an ETH reserve
      *
      * @return true if the converter has an ETH reserve, false otherwise
    */
    function hasETHReserve() public view returns (bool) {
        return reserves[ETH_RESERVE_ADDRESS].isSet;
    }

    /**
      * @dev converts a specific amount of source tokens to target tokens
      * can only be called by the bancor network contract
      *
      * @param _sourceToken source ERC20 token
      * @param _targetToken target ERC20 token
      * @param _amount      amount of tokens to convert (in units of the source token)
      * @param _trader      address of the caller who executed the conversion
      * @param _beneficiary wallet to receive the conversion result
      *
      * @return amount of tokens received (in units of the target token)
    */
    function convert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary)
        public
        payable
        protected
        only(BANCOR_NETWORK)
        returns (uint256)
    {
        // validate input
        require(_sourceToken != _targetToken, "ERR_SAME_SOURCE_TARGET");

        // if a whitelist is set, verify that both and trader and the beneficiary are whitelisted
        require(conversionWhitelist == address(0) ||
                (conversionWhitelist.isWhitelisted(_trader) && conversionWhitelist.isWhitelisted(_beneficiary)),
                "ERR_NOT_WHITELISTED");

        return doConvert(_sourceToken, _targetToken, _amount, _trader, _beneficiary);
    }

    /**
      * @dev converts a specific amount of source tokens to target tokens
      * called by ConverterBase and allows the inherited contracts to implement custom conversion logic
      *
      * @param _sourceToken source ERC20 token
      * @param _targetToken target ERC20 token
      * @param _amount      amount of tokens to convert (in units of the source token)
      * @param _trader      address of the caller who executed the conversion
      * @param _beneficiary wallet to receive the conversion result
      *
      * @return amount of tokens received (in units of the target token)
    */
    function doConvert(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount, address _trader, address _beneficiary) internal returns (uint256);

    /**
      * @dev returns the conversion fee for a given return amount
      *
      * @param _amount  return amount
      *
      * @return conversion fee
    */
    function calculateFee(uint256 _amount) internal view returns (uint256) {
        return _amount.mul(conversionFee).div(CONVERSION_FEE_RESOLUTION);
    }

    /**
      * @dev syncs the stored reserve balance for a given reserve with the real reserve balance
      *
      * @param _reserveToken    address of the reserve token
    */
    function syncReserveBalance(IERC20Token _reserveToken) internal validReserve(_reserveToken) {
        if (_reserveToken == ETH_RESERVE_ADDRESS)
            reserves[_reserveToken].balance = address(this).balance;
        else
            reserves[_reserveToken].balance = _reserveToken.balanceOf(this);
    }

    /**
      * @dev syncs all stored reserve balances
    */
    function syncReserveBalances() internal {
        uint256 reserveCount = reserveTokens.length;
        for (uint256 i = 0; i < reserveCount; i++)
            syncReserveBalance(reserveTokens[i]);
    }

    /**
      * @dev helper, dispatches the Conversion event
      *
      * @param _sourceToken     source ERC20 token
      * @param _targetToken     target ERC20 token
      * @param _trader          address of the caller who executed the conversion
      * @param _amount          amount purchased/sold (in the source token)
      * @param _returnAmount    amount returned (in the target token)
    */
    function dispatchConversionEvent(
        IERC20Token _sourceToken,
        IERC20Token _targetToken,
        address _trader,
        uint256 _amount,
        uint256 _returnAmount,
        uint256 _feeAmount)
        internal
    {
        // fee amount is converted to 255 bits -
        // negative amount means the fee is taken from the source token, positive amount means its taken from the target token
        // currently the fee is always taken from the target token
        // since we convert it to a signed number, we first ensure that it's capped at 255 bits to prevent overflow
        assert(_feeAmount < 2 ** 255);
        emit Conversion(_sourceToken, _targetToken, _trader, _amount, _returnAmount, int256(_feeAmount));
    }

    /**
      * @dev deprecated since version 28, backward compatibility - use only for earlier versions
    */
    function token() public view returns (IConverterAnchor) {
        return anchor;
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function transferTokenOwnership(address _newOwner) public ownerOnly {
        transferAnchorOwnership(_newOwner);
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function acceptTokenOwnership() public ownerOnly {
        acceptAnchorOwnership();
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function connectors(address _address) public view returns (uint256, uint32, bool, bool, bool) {
        Reserve memory reserve = reserves[_address];
        return(reserve.balance, reserve.weight, false, false, reserve.isSet);
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function connectorTokens(uint256 _index) public view returns (IERC20Token) {
        return ConverterBase.reserveTokens[_index];
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function connectorTokenCount() public view returns (uint16) {
        return reserveTokenCount();
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function getConnectorBalance(IERC20Token _connectorToken) public view returns (uint256) {
        return reserveBalance(_connectorToken);
    }

    /**
      * @dev deprecated, backward compatibility
    */
    function getReturn(IERC20Token _sourceToken, IERC20Token _targetToken, uint256 _amount) public view returns (uint256, uint256) {
        return targetAmountAndFee(_sourceToken, _targetToken, _amount);
    }
}

// File: contracts/converter/LiquidityPoolConverter.sol

pragma solidity 0.4.26;


/**
  * @dev Liquidity Pool Converter
  *
  * The liquidity pool converter is the base contract for specific types of converters that
  * manage liquidity pools.
  *
  * Liquidity pools have 2 reserves or more and they allow converting between them.
  *
  * Note that TokenRateUpdate events are dispatched for pool tokens as well.
  * The pool token is the first token in the event in that case.
*/
contract LiquidityPoolConverter is ConverterBase {
    /**
      * @dev triggered after liquidity is added
      *
      * @param  _provider       liquidity provider
      * @param  _reserveToken   reserve token address
      * @param  _amount         reserve token amount
      * @param  _newBalance     reserve token new balance
      * @param  _newSupply      pool token new supply
    */
    event LiquidityAdded(
        address indexed _provider,
        address indexed _reserveToken,
        uint256 _amount,
        uint256 _newBalance,
        uint256 _newSupply
    );

    /**
      * @dev triggered after liquidity is removed
      *
      * @param  _provider       liquidity provider
      * @param  _reserveToken   reserve token address
      * @param  _amount         reserve token amount
      * @param  _newBalance     reserve token new balance
      * @param  _newSupply      pool token new supply
    */
    event LiquidityRemoved(
        address indexed _provider,
        address indexed _reserveToken,
        uint256 _amount,
        uint256 _newBalance,
        uint256 _newSupply
    );

    /**
      * @dev initializes a new LiquidityPoolConverter instance
      *
      * @param  _anchor             anchor governed by the converter
      * @param  _registry           address of a contract registry contract
      * @param  _maxConversionFee   maximum conversion fee, represented in ppm
    */
    constructor(
        IConverterAnchor _anchor,
        IContractRegistry _registry,
        uint32 _maxConversionFee
    )
        ConverterBase(_anchor, _registry, _maxConversionFee)
        internal
    {
    }

    /**
      * @dev accepts ownership of the anchor after an ownership transfer
      * also activates the converter
      * can only be called by the contract owner
      * note that prior to version 28, you should use 'acceptTokenOwnership' instead
    */
    function acceptTokenOwnership() public {
        // verify that the converter has at least 2 reserves
        require(reserveTokenCount() > 1, "ERR_INVALID_RESERVE_COUNT");
        super.acceptTokenOwnership();
    }
}

// File: contracts/converter/interfaces/ITypedConverterFactory.sol

pragma solidity 0.4.26;




/*
    Typed Converter Factory interface
*/
contract ITypedConverterFactory {
    function converterType() public pure returns (uint16);
    function createConverter(IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee) public returns (IConverter);
}

// File: contracts/token/interfaces/ISmartToken.sol

pragma solidity 0.4.26;




/*
    Smart Token interface
*/
contract ISmartToken is IConverterAnchor, IERC20Token {
    function disableTransfers(bool _disable) public;
    function issue(address _to, uint256 _amount) public;
    function destroy(address _from, uint256 _amount) public;
}

// File: contracts/converter/LiquidityPoolV1Converter.sol

pragma solidity 0.4.26;




/*
    LiquidityPoolV1Converter Factory
*/
contract LiquidityPoolV1ConverterFactory is ITypedConverterFactory {
    /**
      * @dev returns the converter type the factory is associated with
      *
      * @return converter type
    */
    function converterType() public pure returns (uint16) {
        return 1;
    }

    /**
      * @dev creates a new converter with the given arguments and transfers
      * the ownership to the caller
      *
      * @param _anchor            anchor governed by the converter
      * @param _registry          address of a contract registry contract
      * @param _maxConversionFee  maximum conversion fee, represented in ppm
      *
      * @return a new converter
    */
    function createConverter(IConverterAnchor _anchor, IContractRegistry _registry, uint32 _maxConversionFee) public returns (IConverter) {
        ConverterBase converter = new LiquidityPoolV1Converter(ISmartToken(_anchor), _registry, _maxConversionFee);
        converter.transferOwnership(msg.sender);
     ...

// [truncated — 74390 bytes total]

Read Contract

anchor 0xd3fb73b4 → address
connectorTokenCount 0x71f52bf3 → uint16
connectorTokens 0x19b64015 → address
connectors 0x0e53aae9 → uint256, uint32, bool, bool, bool
conversionFee 0x579cd3ca → uint32
conversionWhitelist 0xc45d3d92 → address
conversionsEnabled 0xbf754558 → bool
converterType 0x3e8ff43f → uint16
decimalLength 0x6aa5332c → uint256
geometricMean 0xa60e7724 → uint256
getConnectorBalance 0xd8959512 → uint256
getReturn 0x1e1401f8 → uint256, uint256
hasETHReserve 0x12c2aca4 → bool
isActive 0x22f3e2d4 → bool
isV28OrHigher 0xd260529c → bool
maxConversionFee 0x94c275ad → uint32
newOwner 0xd4ee1d90 → address
onlyOwnerCanUpdateRegistry 0x2fe8a6ad → bool
owner 0x8da5cb5b → address
prevRegistry 0x61cd756e → address
registry 0x7b103999 → address
reserveBalance 0xdc8de379 → uint256
reserveRatio 0x0c7d5cd8 → uint32
reserveTokenCount 0x9b99a8e2 → uint16
reserveTokens 0xd031370b → address
reserveWeight 0x1cfab290 → uint32
reserves 0xd66bd524 → uint256, uint32, bool, bool, bool
roundDiv 0xbbb7e5d8 → uint256
targetAmountAndFee 0xaf94b8d8 → uint256, uint256
token 0xfc0c546a → address
version 0x54fd4d50 → uint16

Write Contract 21 functions

These functions modify contract state and require a wallet transaction to execute.

acceptAnchorOwnership 0xcdc91c69
No parameters
acceptOwnership 0x79ba5097
No parameters
acceptTokenOwnership 0x38a5e016
No parameters
addLiquidity 0x7d8916bd
address[] _reserveTokens
uint256[] _reserveAmounts
uint256 _minReturn
addReserve 0x6a49d2c4
address _token
uint32 _weight
convert 0xe8dc12ff
address _sourceToken
address _targetToken
uint256 _amount
address _trader
address _beneficiary
returns: uint256
fund 0xca1d209d
uint256 _amount
liquidate 0x415f1240
uint256 _amount
removeLiquidity 0xb127c0a5
uint256 _amount
address[] _reserveTokens
uint256[] _reserveMinReturnAmounts
restoreRegistry 0xb4a176d3
No parameters
restrictRegistryUpdate 0x024c7ec7
bool _onlyOwnerCanUpdateRegistry
setConversionFee 0xecbca55d
uint32 _conversionFee
setConversionWhitelist 0x4af80f0e
address _whitelist
transferAnchorOwnership 0x67b6d57c
address _newOwner
transferOwnership 0xf2fde38b
address _newOwner
transferTokenOwnership 0x21e6b53d
address _newOwner
updateRegistry 0x49d10b64
No parameters
upgrade 0xd55ec697
No parameters
withdrawETH 0x690d8320
address _to
withdrawFromAnchor 0x395900d4
address _token
address _to
uint256 _amount
withdrawTokens 0x5e35359e
address _token
address _to
uint256 _amount

Recent Transactions

No transactions found for this address