Skip to content

Instantly share code, notes, and snippets.

@jeffywu
Last active June 30, 2021 14:00
Show Gist options
  • Save jeffywu/4baf31b1a3b6cd4e1bbc5d3b2c70e55d to your computer and use it in GitHub Desktop.
Save jeffywu/4baf31b1a3b6cd4e1bbc5d3b2c70e55d to your computer and use it in GitHub Desktop.
NotionalV1 to Compound
import os
import json
from brownie import (
accounts,
NotionalV1ToCompound,
nTransparentUpgradeableProxy
)
from brownie.network import web3
from brownie.network.contract import Contract
def main():
deployer = accounts.add(private_key=os.environ["TESTNET_PRIVATE_KEY"])
with open("kovan.json", "r") as f:
addresses = json.load(f)
with open("./ERC1155Trade.json", "r") as f:
ERC1155Artifact = json.load(f)
with open("./ERC20.json", "r") as f:
ERC20 = json.load(f)
v1ToComp = NotionalV1ToCompound.deploy(
addresses["escrow"],
addresses["erc1155trade"],
addresses["wETHwBTCUniswapV2"],
addresses["WETH"],
addresses["WBTC"],
addresses["comptroller"],
addresses["cETH"],
addresses["cDAI"],
addresses["cUSDC"],
addresses["cWBTC"],
{"from": deployer}
)
initializeData = web3.eth.contract(abi=NotionalV1ToCompound.abi).encodeABI(
fn_name="initialize", args=[]
)
proxy = nTransparentUpgradeableProxy.deploy(
v1ToComp.address,
addresses["proxyAdmin"], # Set your own proxy admin here...
initializeData, # Deployer is set to owner
{"from": deployer},
)
migrator = Contract.from_abi(
"Notional", proxy.address, abi=NotionalV1ToCompound.abi, owner=deployer
)
erc1155 = Contract.from_abi(
"ERC1155Trade", address=addresses["erc1155trade"], abi=ERC1155Artifact['abi']
)
usdc = Contract.from_abi(
"USDC", address=addresses["USDC"], abi=ERC20
)
erc1155.setApprovalForAll(migrator.address, True, {"from": deployer})
usdc.approve(addresses["escrow"], 2 ** 255, {"from": deployer})
# Get this value from etherscan
v1RepayAmount = 1023298128
migrator.migrateUSDCEther(v1RepayAmount, {'from': deployer})
{
"contractName": "ERC1155Trade",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "_approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "BatchOperation",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "_ids",
"type": "uint256[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "_values",
"type": "uint256[]"
}
],
"name": "TransferBatch",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_operator",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "_value",
"type": "uint256"
}
],
"name": "TransferSingle",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "_value",
"type": "string"
},
{
"indexed": true,
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"name": "URI",
"type": "event"
},
{
"inputs": [],
"name": "BRIDGE_PROXY",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DIRECTORY",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "accounts",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "ids",
"type": "uint256[]"
}
],
"name": "balanceOfBatch",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint32",
"name": "maxTime",
"type": "uint32"
},
{
"components": [
{
"internalType": "uint16",
"name": "currencyId",
"type": "uint16"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
}
],
"internalType": "struct Common.Deposit[]",
"name": "deposits",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "enum Common.TradeType",
"name": "tradeType",
"type": "uint8"
},
{
"internalType": "uint8",
"name": "cashGroup",
"type": "uint8"
},
{
"internalType": "uint32",
"name": "maturity",
"type": "uint32"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"internalType": "bytes",
"name": "slippageData",
"type": "bytes"
}
],
"internalType": "struct Common.Trade[]",
"name": "trades",
"type": "tuple[]"
}
],
"name": "batchOperation",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint32",
"name": "maxTime",
"type": "uint32"
},
{
"components": [
{
"internalType": "uint16",
"name": "currencyId",
"type": "uint16"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
}
],
"internalType": "struct Common.Deposit[]",
"name": "deposits",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "enum Common.TradeType",
"name": "tradeType",
"type": "uint8"
},
{
"internalType": "uint8",
"name": "cashGroup",
"type": "uint8"
},
{
"internalType": "uint32",
"name": "maturity",
"type": "uint32"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
},
{
"internalType": "bytes",
"name": "slippageData",
"type": "bytes"
}
],
"internalType": "struct Common.Trade[]",
"name": "trades",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint16",
"name": "currencyId",
"type": "uint16"
},
{
"internalType": "uint128",
"name": "amount",
"type": "uint128"
}
],
"internalType": "struct Common.Withdraw[]",
"name": "withdraws",
"type": "tuple[]"
}
],
"name": "batchOperationWithdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "decodeAssetId",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
},
{
"internalType": "uint16",
"name": "",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "",
"type": "uint32"
},
{
"internalType": "bytes1",
"name": "",
"type": "bytes1"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint8",
"name": "cashGroupId",
"type": "uint8"
},
{
"internalType": "uint16",
"name": "instrumentId",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "maturity",
"type": "uint32"
},
{
"internalType": "bytes1",
"name": "assetType",
"type": "bytes1"
}
],
"name": "encodeAssetId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "uint8",
"name": "cashGroupId",
"type": "uint8"
},
{
"internalType": "uint16",
"name": "instrumentId",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "maturity",
"type": "uint32"
},
{
"internalType": "bytes1",
"name": "assetType",
"type": "bytes1"
},
{
"internalType": "uint32",
"name": "rate",
"type": "uint32"
},
{
"internalType": "uint128",
"name": "notional",
"type": "uint128"
}
],
"internalType": "struct Common.Asset",
"name": "asset",
"type": "tuple"
}
],
"name": "encodeAssetId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "directory",
"type": "address"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isOwner",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "operators",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
},
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "safeBatchTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "bridgeProxy",
"type": "address"
}
],
"name": "setBridgeProxy",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "enum Governed.CoreContracts",
"name": "name",
"type": "uint8"
},
{
"internalType": "address",
"name": "contractAddress",
"type": "address"
}
],
"name": "setContract",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x60806040819052600080546001600160a01b03191633178082556001600160a01b0316917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3612dbe806100576000396000f3fe6080604052600436106101345760003560e01c8063865e6fd3116100ab578063a22cb4651161006f578063a22cb46514610342578063a571e18414610362578063cea107b714610382578063e985e9c514610397578063f242432a146103b7578063f2fde38b146103d757610134565b8063865e6fd3146102c357806388bc2ef3146102e357806389f6ca37146103055780638da5cb5b146103185780638f32d59b1461032d57610134565b8063485cc955116100fd578063485cc955146101fe5780634e1273f41461021e5780635ecee7e01461024b5780636322c7511461026b578063715018a61461029b57806378cf71f2146102b057610134565b8062fdd58e1461013957806301ffc9a71461016f5780632637588e1461019c5780632e7256a4146101bc5780632eb2c2d6146101dc575b600080fd5b34801561014557600080fd5b5061015961015436600461224e565b6103f7565b6040516101669190612c3a565b60405180910390f35b34801561017b57600080fd5b5061018f61018a366004612552565b6104c6565b6040516101669190612b1e565b3480156101a857600080fd5b5061018f6101b73660046120b0565b6104ea565b3480156101c857600080fd5b506101596101d7366004612840565b61050a565b3480156101e857600080fd5b506101fc6101f73660046120e8565b61056e565b005b34801561020a57600080fd5b506101fc6102193660046120b0565b61058f565b34801561022a57600080fd5b5061023e610239366004612448565b61065b565b6040516101669190612ada565b34801561025757600080fd5b506101596102663660046125af565b610768565b34801561027757600080fd5b5061028b610286366004612792565b610787565b6040516101669493929190612c5f565b3480156102a757600080fd5b506101fc6107bc565b6101fc6102be3660046122ff565b610817565b3480156102cf57600080fd5b506101fc6102de36600461257a565b610ada565b3480156102ef57600080fd5b506102f8610b4b565b604051610166919061289b565b6101fc610313366004612279565b610b5a565b34801561032457600080fd5b506102f8610d9f565b34801561033957600080fd5b5061018f610dae565b34801561034e57600080fd5b506101fc61035d36600461221d565b610dbf565b34801561036e57600080fd5b506101fc61037d366004612094565b610e2e565b34801561038e57600080fd5b506102f8610e61565b3480156103a357600080fd5b5061018f6103b23660046120b0565b610e70565b3480156103c357600080fd5b506101fc6103d23660046121a3565b610e9e565b3480156103e357600080fd5b506101fc6103f2366004612094565b611188565b600080610403836111a5565b90506000806000610413866111ab565b925092509250610421611d9e565b6104296111ca565b6001600160a01b031663b4df02cd89878787876040518663ffffffff1660e01b815260040161045c9594939291906129cc565b60e06040518083038186803b15801561047457600080fd5b505afa158015610488573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ac9190612654565b5060a001516001600160801b031698975050505050505050565b60006001600160e01b03198216636cdb3d1360e11b14156104e5575060015b919050565b603560209081526000928352604080842090915290825290205460ff1681565b6000610514611d9e565b506040805160c08101825260ff8716815261ffff8616602082015263ffffffff8516918101919091526001600160f81b03198316606082015260006080820181905260a0820152610564816111f1565b9695505050505050565b60405162461bcd60e51b815260040161058690612c1e565b60405180910390fd5b600054600160a81b900460ff16806105aa57506105aa61124b565b806105bf5750600054600160a01b900460ff16155b6105db5760405162461bcd60e51b815260040161058690612bb5565b600054600160a81b900460ff16158015610612576000805460ff60a01b1960ff60a81b19909116600160a81b1716600160a01b1790555b600080546001600160a01b038085166001600160a01b03199283161790925560338054928616929091169190911790558015610656576000805460ff60a81b191690555b505050565b6060808585905060405190808252806020026020018201604052801561068b578160200160208202803683370190505b50905060005b8581101561075e573062fdd58e8888848181106106aa57fe5b90506020020160208101906106bf9190612094565b8787858181106106cb57fe5b905060200201356040518363ffffffff1660e01b81526004016106ef929190612a11565b60206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190612597565b82828151811061074b57fe5b6020908102919091010152600101610691565b5095945050505050565b600061078161077c368490038401846125c6565b6111f1565b92915050565b6000806000806000610798866111a5565b905060008060006107a8896111ab565b919950975095509293505050509193509193565b6107c4610dae565b6107cd57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b4263ffffffff80861690821611156108415760405162461bcd60e51b815260040161058690612b99565b336001600160a01b038716148061085d575061085d8633610e70565b6108795760405162461bcd60e51b815260040161058690612b7d565b6108816111ca565b6001600160a01b031663265bf4cf876040518263ffffffff1660e01b81526004016108ac919061289b565b600060405180830381600087803b1580156108c657600080fd5b505af11580156108da573d6000803e3d6000fd5b5050505060606000855111806108ef57503415155b1561095d576108fc611251565b6001600160a01b031663e4a833003489886040518463ffffffff1660e01b815260040161092a9291906128f1565b6000604051808303818588803b15801561094357600080fd5b505af1158015610957573d6000803e3d6000fd5b50505050505b8351156109715761096e878561125c565b90505b8251156109f25780511561098a5761098a8186856119db565b610992611251565b6001600160a01b031663422c32cd88856040518363ffffffff1660e01b81526004016109bf929190612950565b600060405180830381600087803b1580156109d957600080fd5b505af11580156109ed573d6000803e3d6000fd5b505050505b60006109fc6111ca565b6001600160a01b031663f9a4cb1b896040518263ffffffff1660e01b8152600401610a27919061289b565b60206040518083038186803b158015610a3f57600080fd5b505afa158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a779190612597565b90506000811215610a9a5760405162461bcd60e51b815260040161058690612c03565b60405133906001600160a01b038a16907f15258dcf35dab69581a17d65f7d1b639636265628d7ed1225dcac1081796c7b890600090a35050505050505050565b6033546001600160a01b03163314610b045760405162461bcd60e51b815260040161058690612b7d565b8060346000846003811115610b1557fe5b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6033546001600160a01b031681565b4263ffffffff8085169082161115610b845760405162461bcd60e51b815260040161058690612b99565b336001600160a01b0386161480610ba05750610ba08533610e70565b610bbc5760405162461bcd60e51b815260040161058690612b7d565b610bc46111ca565b6001600160a01b031663265bf4cf866040518263ffffffff1660e01b8152600401610bef919061289b565b600060405180830381600087803b158015610c0957600080fd5b505af1158015610c1d573d6000803e3d6000fd5b50505050600083511180610c3057503415155b15610c9e57610c3d611251565b6001600160a01b031663e4a833003487866040518463ffffffff1660e01b8152600401610c6b9291906128f1565b6000604051808303818588803b158015610c8457600080fd5b505af1158015610c98573d6000803e3d6000fd5b50505050505b815115610cb157610caf858361125c565b505b815115610d62576000610cc26111ca565b6001600160a01b031663f9a4cb1b876040518263ffffffff1660e01b8152600401610ced919061289b565b60206040518083038186803b158015610d0557600080fd5b505afa158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190612597565b90506000811215610d605760405162461bcd60e51b815260040161058690612c03565b505b60405133906001600160a01b038716907f15258dcf35dab69581a17d65f7d1b639636265628d7ed1225dcac1081796c7b890600090a35050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b3360008181526035602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190610e22908590612b1e565b60405180910390a35050565b610e36610dae565b610e3f57600080fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b6036546001600160a01b031681565b6001600160a01b03918216600090815260356020908152604080832093909416825291909152205460ff1690565b6036546001600160a01b0316331480610ecf57506001600160a01b03861633148015610ecf5750610ecf8587610e70565b80610ef05750610edf8633610e70565b8015610ef05750610ef08533610e70565b610f0c5760405162461bcd60e51b815260040161058690612b7d565b6001600160801b03831115610f335760405162461bcd60e51b815260040161058690612b46565b60608115610f4a57610f47828401846124b1565b90505b6000610f55866111a5565b9050600080610f63886111ab565b9250509150610f7183611a71565b15611056578415610fe457610f84611251565b6001600160a01b031663e4a833008a866040518363ffffffff1660e01b8152600401610fb19291906128f1565b600060405180830381600087803b158015610fcb57600080fd5b505af1158015610fdf573d6000803e3d6000fd5b505050505b610fec6111ca565b6001600160a01b03166316745ae88a8c85858c6040518663ffffffff1660e01b815260040161101f9594939291906128af565b600060405180830381600087803b15801561103957600080fd5b505af115801561104d573d6000803e3d6000fd5b50505050611125565b61105f83611a8c565b1561110d5784156110d257611072611251565b6001600160a01b031663e4a833008b866040518363ffffffff1660e01b815260040161109f9291906128f1565b600060405180830381600087803b1580156110b957600080fd5b505af11580156110cd573d6000803e3d6000fd5b505050505b6110da6111ca565b6001600160a01b03166316745ae88b8b85858c6040518663ffffffff1660e01b815260040161101f9594939291906128af565b60405162461bcd60e51b815260040161058690612b62565b886001600160a01b03168a6001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b604051611174929190612c43565b60405180910390a450505050505050505050565b611190610dae565b61119957600080fd5b6111a281611abe565b50565b60f81b90565b603881901c60ff1691602882901c61ffff169160081c63ffffffff1690565b600060348160015b81526020810191909152604001600020546001600160a01b0316905090565b606081015160408201516020830151835160f81b6001600160f81b03191661ffff60e81b60e89290921b919091161763ffffffff60c81b60c89290921b919091161760ff60c01b60389290921c919091161760c01c919050565b303b1590565b6000603481806111d2565b606080825160405190808252806020026020018201604052801561129a57816020015b611287611dd3565b81526020019060019003908161127f5790505b50905060005b83518110156119d3576112b1611df5565b6112b96111ca565b6001600160a01b0316636dab47fd8684815181106112d357fe5b6020026020010151602001516040518263ffffffff1660e01b81526004016112fb9190612c51565b60a06040518083038186803b15801561131357600080fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b91906126fb565b6060810151909150600086848151811061136157fe5b602002602001015160000151600381111561137857fe5b141561152357600086848151811061138c57fe5b60200260200101516080015151602014156113d3578684815181106113ad57fe5b6020026020010151608001518060200190518101906113cc91906127aa565b90506113da565b5063ffffffff5b82608001518585815181106113eb57fe5b60200260200101516000019061ffff16908161ffff1681525050600085858151811061141357fe5b602002602001015160200190600381111561142a57fe5b9081600381111561143757fe5b81525050816001600160a01b0316630f6362568989878151811061145757fe5b6020026020010151604001518a888151811061146f57fe5b602002602001015160600151856040518563ffffffff1660e01b815260040161149b9493929190612aa2565b602060405180830381600087803b1580156114b557600080fd5b505af11580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190612776565b8585815181106114f957fe5b6020026020010151604001906001600160801b031690816001600160801b031681525050506119c9565b600186848151811061153157fe5b602002602001015160000151600381111561154857fe5b141561161c57600086848151811061155c57fe5b602002602001015160800151516020141561159f5786848151811061157d57fe5b60200260200101516080015180602001905181019061159c91906127aa565b90505b82608001518585815181106115b057fe5b60200260200101516000019061ffff16908161ffff168152505060018585815181106115d857fe5b60200260200101516020019060038111156115ef57fe5b908160038111156115fc57fe5b81525050816001600160a01b031663d6789ec08989878151811061145757fe5b600286848151811061162a57fe5b602002602001015160000151600381111561164157fe5b141561185c57600080600088868151811061165857fe5b60200260200101516080015151604014156116ac5788868151811061167957fe5b60200260200101516080015180602001905181019061169891906127c6565b90935091506001600160801b039050611715565b8886815181106116b857fe5b6020026020010151608001515160601415611704578886815181106116d957fe5b6020026020010151608001518060200190518101906116f891906127f4565b91945092509050611715565b5063ffffffff90506001600160801b035b846080015187878151811061172657fe5b60200260200101516000019061ffff16908161ffff1681525050600287878151811061174e57fe5b602002602001015160200190600381111561176557fe5b9081600381111561177257fe5b8152505088868151811061178257fe5b60200260200101516060015187878151811061179a57fe5b6020026020010151604001906001600160801b031690816001600160801b031681525050836001600160a01b03166389dd65b08b8b89815181106117da57fe5b6020026020010151604001518c8a815181106117f257fe5b6020026020010151606001518588886040518763ffffffff1660e01b815260040161182296959493929190612a5a565b600060405180830381600087803b15801561183c57600080fd5b505af1158015611850573d6000803e3d6000fd5b505050505050506119c9565b600386848151811061186a57fe5b602002602001015160000151600381111561188157fe5b14156119c957816080015184848151811061189857fe5b60200260200101516000019061ffff16908161ffff168152505060038484815181106118c057fe5b60200260200101516020019060038111156118d757fe5b908160038111156118e457fe5b81525050806001600160a01b0316634e9a6c308888868151811061190457fe5b60200260200101516040015189878151811061191c57fe5b6020026020010151606001516040518463ffffffff1660e01b815260040161194693929190612a2a565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612776565b8484815181106119a457fe5b6020026020010151604001906001600160801b031690816001600160801b0316815250505b50506001016112a0565b509392505050565b60005b8151811015611a6b578181815181106119f357fe5b6020026020010151604001516001600160801b031660001415611a6357611a32828281518110611a1f57fe5b6020026020010151602001518585611b2c565b828281518110611a3e57fe5b6020026020010151604001906001600160801b031690816001600160801b0316815250505b6001016119de565b50505050565b6000611a7c82611d11565b8015610781575061078182611d2f565b6000611a9782611d11565b8015611aa75750611aa782611d3b565b80156107815750611ab782611d47565b1592915050565b6001600160a01b038116611ad157600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008060005b8351811015611b89578561ffff16848281518110611b4c57fe5b60200260200101516000015161ffff161415611b8157838181518110611b6e57fe5b6020026020010151602001519150611b89565b600101611b32565b5060005b8451811015611d08578561ffff16858281518110611ba757fe5b60200260200101516000015161ffff1614611bc157611d00565b6000858281518110611bcf57fe5b6020026020010151602001516003811115611be657fe5b1480611c1457506003858281518110611bfb57fe5b6020026020010151602001516003811115611c1257fe5b145b15611c5357611c4c858281518110611c2857fe5b602002602001015160400151836001600160801b0316611d6690919063ffffffff16565b9150611d00565b6001858281518110611c6157fe5b6020026020010151602001516003811115611c7857fe5b1480611ca657506002858281518110611c8d57fe5b6020026020010151602001516003811115611ca457fe5b145b15611d0057848181518110611cb757fe5b6020026020010151604001516001600160801b0316826001600160801b031610611cfa57848181518110611ce757fe5b6020026020010151604001518203611cfd565b60005b91505b600101611b8d565b50949350505050565b6000600160fa1b8216158015610781575050600160fb1b9081161490565b600160fc1b9081161490565b600160fd1b9081161490565b6000600160fa1b828116148015610781575050600160fb1b9081161490565b60008282016001600160801b038085169082161015611d975760405162461bcd60e51b815260040161058690612b29565b9392505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040805160608101909152600080825260208201908152600060209091015290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b60008083601f840112611e34578182fd5b50813567ffffffffffffffff811115611e4b578182fd5b6020830191508360208083028501011115611e6557600080fd5b9250929050565b600082601f830112611e7c578081fd5b8135611e8f611e8a82612cba565b612c93565b8181529150602080830190848101604080850287018301881015611eb257600080fd5b60005b85811015611ed957611ec78984612051565b85529383019391810191600101611eb5565b50505050505092915050565b600082601f830112611ef5578081fd5b8135611f03611e8a82612cba565b818152915060208083019084810160005b84811015612006578135870160a080601f19838c03011215611f3557600080fd5b611f3e81612c93565b85830135611f4b81612d35565b8152604083810135611f5c81612d79565b82880152606084810135611f6f81612d67565b83830152608085810135611f8281612d42565b80838601525084860135915067ffffffffffffffff821115611fa357600080fd5b81860194508d603f860112611fb757600080fd5b888501359550611fc9611e8a87612cda565b91508582528d83878701011115611fdf57600080fd5b611fee868a8401858801612cfe565b83015250865250509282019290820190600101611f14565b505050505092915050565b60008083601f840112612022578182fd5b50813567ffffffffffffffff811115612039578182fd5b602083019150836020828501011115611e6557600080fd5b600060408284031215612062578081fd5b61206c6040612c93565b9050813561207981612d57565b8152602082013561208981612d42565b602082015292915050565b6000602082840312156120a5578081fd5b8135611d9781612d0a565b600080604083850312156120c2578081fd5b82356120cd81612d0a565b915060208301356120dd81612d0a565b809150509250929050565b60008060008060008060008060a0898b031215612103578384fd5b883561210e81612d0a565b9750602089013561211e81612d0a565b9650604089013567ffffffffffffffff8082111561213a578586fd5b6121468c838d01611e23565b909850965060608b013591508082111561215e578586fd5b61216a8c838d01611e23565b909650945060808b0135915080821115612182578384fd5b5061218f8b828c01612011565b999c989b5096995094979396929594505050565b60008060008060008060a087890312156121bb578384fd5b86356121c681612d0a565b955060208701356121d681612d0a565b94506040870135935060608701359250608087013567ffffffffffffffff8111156121ff578283fd5b61220b89828a01612011565b979a9699509497509295939492505050565b6000806040838503121561222f578182fd5b823561223a81612d0a565b9150602083013580151581146120dd578182fd5b60008060408385031215612260578182fd5b823561226b81612d0a565b946020939093013593505050565b6000806000806080858703121561228e578182fd5b843561229981612d0a565b935060208501356122a981612d67565b9250604085013567ffffffffffffffff808211156122c5578384fd5b6122d188838901611e6c565b935060608701359150808211156122e6578283fd5b506122f387828801611ee5565b91505092959194509250565b600080600080600060a08688031215612316578283fd5b853561232181612d0a565b945060208681013561233281612d67565b9450604087013567ffffffffffffffff8082111561234e578586fd5b61235a8a838b01611e6c565b9550606091508189013581811115612370578485fd5b61237c8b828c01611ee5565b955050608089013581811115612390578485fd5b89019050601f81018a136123a2578384fd5b80356123b0611e8a82612cba565b81815284810190838601858402850187018e10156123cc578788fd5b8794505b838510156124345785818f0312156123e6578788fd5b6123ef86612c93565b81356123fa81612d0a565b81528188013561240981612d57565b81890152604082013561241b81612d42565b60408201528352600194909401939186019185016123d0565b508096505050505050509295509295909350565b6000806000806040858703121561245d578182fd5b843567ffffffffffffffff80821115612474578384fd5b61248088838901611e23565b90965094506020870135915080821115612498578384fd5b506124a587828801611e23565b95989497509550505050565b600060208083850312156124c3578182fd5b823567ffffffffffffffff8111156124d9578283fd5b80840185601f8201126124ea578384fd5b803591506124fa611e8a83612cba565b828152838101908285016040808602850187018a1015612518578788fd5b8794505b858510156125445761252e8a83612051565b845260019490940193928601929081019061251c565b509098975050505050505050565b600060208284031215612563578081fd5b81356001600160e01b031981168114611d97578182fd5b6000806040838503121561258c578182fd5b82356120cd81612d35565b6000602082840312156125a8578081fd5b5051919050565b600060c082840312156125c0578081fd5b50919050565b600060c082840312156125d7578081fd5b6125e160c0612c93565b82356125ec81612d79565b815260208301356125fc81612d57565b6020820152604083013561260f81612d67565b6040820152606083013561262281612d1f565b6060820152608083013561263581612d67565b608082015260a083013561264881612d42565b60a08201529392505050565b60008082840360e0811215612667578283fd5b60c0811215612674578283fd5b5061267f60c0612c93565b835161268a81612d79565b8152602084015161269a81612d57565b602082015260408401516126ad81612d67565b604082015260608401516126c081612d1f565b606082015260808401516126d381612d67565b608082015260a08401516126e681612d42565b60a082015260c0939093015192949293505050565b600060a0828403121561270c578081fd5b61271660a0612c93565b825161272181612d67565b8152602083015161273181612d67565b6020820152604083015161274481612d67565b6040820152606083015161275781612d0a565b6060820152608083015161276a81612d57565b60808201529392505050565b600060208284031215612787578081fd5b8151611d9781612d42565b6000602082840312156127a3578081fd5b5035919050565b6000602082840312156127bb578081fd5b8151611d9781612d67565b600080604083850312156127d8578182fd5b82516127e381612d67565b60208401519092506120dd81612d67565b600080600060608486031215612808578081fd5b835161281381612d67565b602085015190935061282481612d67565b604085015190925061283581612d42565b809150509250925092565b60008060008060808587031215612855578182fd5b843561286081612d79565b9350602085013561287081612d57565b9250604085013561288081612d67565b9150606085013561289081612d1f565b939692955090935050565b6001600160a01b0391909116815260200190565b6001600160a01b03958616815293909416602084015260ff91909116604083015263ffffffff1660608201526001600160801b03909116608082015260a00190565b6001600160a01b038316815260406020808301829052835183830181905260009291858101916060860190855b81811015612544578451805161ffff1684528401516001600160801b031684840152938301939185019160010161291e565b6001600160a01b038381168252604060208084018290528451848301819052600093606092909183870190888301875b828110156129bc5781518051871685528581015161ffff16868601528801516001600160801b0316888501529286019290840190600101612980565b50919a9950505050505050505050565b6001600160a01b039590951685526001600160f81b031993909316602085015260ff91909116604084015261ffff16606083015263ffffffff16608082015260a00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393909316835263ffffffff9190911660208301526001600160801b0316604082015260600190565b6001600160a01b0396909616865263ffffffff94851660208701526001600160801b03938416604087015291909216606085015290821660808401521660a082015260c00190565b6001600160a01b0394909416845263ffffffff92831660208501526001600160801b0391909116604084015216606082015260800190565b6020808252825182820181905260009190848201906040850190845b81811015612b1257835183529284019291840191600101612af6565b50909695505050505050565b901515815260200190565b6020808252600390820152620c4c0d60ea1b604082015260600190565b6020808252600290820152610d0d60f21b604082015260600190565b6020808252600190820152603760f81b604082015260600190565b602080825260029082015261032360f41b604082015260600190565b602080825260029082015261062760f31b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600190820152603560f81b604082015260600190565b602080825260029082015261191960f11b604082015260600190565b90815260200190565b918252602082015260400190565b60ff91909116815260200190565b60ff94909416845261ffff92909216602084015263ffffffff1660408301526001600160f81b031916606082015260800190565b60405181810167ffffffffffffffff81118282101715612cb257600080fd5b604052919050565b600067ffffffffffffffff821115612cd0578081fd5b5060209081020190565b600067ffffffffffffffff821115612cf0578081fd5b50601f01601f191660200190565b82818337506000910152565b6001600160a01b03811681146111a257600080fd5b6001600160f81b0319811681146111a257600080fd5b600481106111a257600080fd5b6001600160801b03811681146111a257600080fd5b61ffff811681146111a257600080fd5b63ffffffff811681146111a257600080fd5b60ff811681146111a257600080fdfea2646970667358221220fa9cd7e8d6a94076927516b2b2da6d02764b07646eadf3f41b46ff41fe6c059d64736f6c63430006040033",
"deployedBytecode": "0x6080604052600436106101345760003560e01c8063865e6fd3116100ab578063a22cb4651161006f578063a22cb46514610342578063a571e18414610362578063cea107b714610382578063e985e9c514610397578063f242432a146103b7578063f2fde38b146103d757610134565b8063865e6fd3146102c357806388bc2ef3146102e357806389f6ca37146103055780638da5cb5b146103185780638f32d59b1461032d57610134565b8063485cc955116100fd578063485cc955146101fe5780634e1273f41461021e5780635ecee7e01461024b5780636322c7511461026b578063715018a61461029b57806378cf71f2146102b057610134565b8062fdd58e1461013957806301ffc9a71461016f5780632637588e1461019c5780632e7256a4146101bc5780632eb2c2d6146101dc575b600080fd5b34801561014557600080fd5b5061015961015436600461224e565b6103f7565b6040516101669190612c3a565b60405180910390f35b34801561017b57600080fd5b5061018f61018a366004612552565b6104c6565b6040516101669190612b1e565b3480156101a857600080fd5b5061018f6101b73660046120b0565b6104ea565b3480156101c857600080fd5b506101596101d7366004612840565b61050a565b3480156101e857600080fd5b506101fc6101f73660046120e8565b61056e565b005b34801561020a57600080fd5b506101fc6102193660046120b0565b61058f565b34801561022a57600080fd5b5061023e610239366004612448565b61065b565b6040516101669190612ada565b34801561025757600080fd5b506101596102663660046125af565b610768565b34801561027757600080fd5b5061028b610286366004612792565b610787565b6040516101669493929190612c5f565b3480156102a757600080fd5b506101fc6107bc565b6101fc6102be3660046122ff565b610817565b3480156102cf57600080fd5b506101fc6102de36600461257a565b610ada565b3480156102ef57600080fd5b506102f8610b4b565b604051610166919061289b565b6101fc610313366004612279565b610b5a565b34801561032457600080fd5b506102f8610d9f565b34801561033957600080fd5b5061018f610dae565b34801561034e57600080fd5b506101fc61035d36600461221d565b610dbf565b34801561036e57600080fd5b506101fc61037d366004612094565b610e2e565b34801561038e57600080fd5b506102f8610e61565b3480156103a357600080fd5b5061018f6103b23660046120b0565b610e70565b3480156103c357600080fd5b506101fc6103d23660046121a3565b610e9e565b3480156103e357600080fd5b506101fc6103f2366004612094565b611188565b600080610403836111a5565b90506000806000610413866111ab565b925092509250610421611d9e565b6104296111ca565b6001600160a01b031663b4df02cd89878787876040518663ffffffff1660e01b815260040161045c9594939291906129cc565b60e06040518083038186803b15801561047457600080fd5b505afa158015610488573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104ac9190612654565b5060a001516001600160801b031698975050505050505050565b60006001600160e01b03198216636cdb3d1360e11b14156104e5575060015b919050565b603560209081526000928352604080842090915290825290205460ff1681565b6000610514611d9e565b506040805160c08101825260ff8716815261ffff8616602082015263ffffffff8516918101919091526001600160f81b03198316606082015260006080820181905260a0820152610564816111f1565b9695505050505050565b60405162461bcd60e51b815260040161058690612c1e565b60405180910390fd5b600054600160a81b900460ff16806105aa57506105aa61124b565b806105bf5750600054600160a01b900460ff16155b6105db5760405162461bcd60e51b815260040161058690612bb5565b600054600160a81b900460ff16158015610612576000805460ff60a01b1960ff60a81b19909116600160a81b1716600160a01b1790555b600080546001600160a01b038085166001600160a01b03199283161790925560338054928616929091169190911790558015610656576000805460ff60a81b191690555b505050565b6060808585905060405190808252806020026020018201604052801561068b578160200160208202803683370190505b50905060005b8581101561075e573062fdd58e8888848181106106aa57fe5b90506020020160208101906106bf9190612094565b8787858181106106cb57fe5b905060200201356040518363ffffffff1660e01b81526004016106ef929190612a11565b60206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190612597565b82828151811061074b57fe5b6020908102919091010152600101610691565b5095945050505050565b600061078161077c368490038401846125c6565b6111f1565b92915050565b6000806000806000610798866111a5565b905060008060006107a8896111ab565b919950975095509293505050509193509193565b6107c4610dae565b6107cd57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b4263ffffffff80861690821611156108415760405162461bcd60e51b815260040161058690612b99565b336001600160a01b038716148061085d575061085d8633610e70565b6108795760405162461bcd60e51b815260040161058690612b7d565b6108816111ca565b6001600160a01b031663265bf4cf876040518263ffffffff1660e01b81526004016108ac919061289b565b600060405180830381600087803b1580156108c657600080fd5b505af11580156108da573d6000803e3d6000fd5b5050505060606000855111806108ef57503415155b1561095d576108fc611251565b6001600160a01b031663e4a833003489886040518463ffffffff1660e01b815260040161092a9291906128f1565b6000604051808303818588803b15801561094357600080fd5b505af1158015610957573d6000803e3d6000fd5b50505050505b8351156109715761096e878561125c565b90505b8251156109f25780511561098a5761098a8186856119db565b610992611251565b6001600160a01b031663422c32cd88856040518363ffffffff1660e01b81526004016109bf929190612950565b600060405180830381600087803b1580156109d957600080fd5b505af11580156109ed573d6000803e3d6000fd5b505050505b60006109fc6111ca565b6001600160a01b031663f9a4cb1b896040518263ffffffff1660e01b8152600401610a27919061289b565b60206040518083038186803b158015610a3f57600080fd5b505afa158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a779190612597565b90506000811215610a9a5760405162461bcd60e51b815260040161058690612c03565b60405133906001600160a01b038a16907f15258dcf35dab69581a17d65f7d1b639636265628d7ed1225dcac1081796c7b890600090a35050505050505050565b6033546001600160a01b03163314610b045760405162461bcd60e51b815260040161058690612b7d565b8060346000846003811115610b1557fe5b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6033546001600160a01b031681565b4263ffffffff8085169082161115610b845760405162461bcd60e51b815260040161058690612b99565b336001600160a01b0386161480610ba05750610ba08533610e70565b610bbc5760405162461bcd60e51b815260040161058690612b7d565b610bc46111ca565b6001600160a01b031663265bf4cf866040518263ffffffff1660e01b8152600401610bef919061289b565b600060405180830381600087803b158015610c0957600080fd5b505af1158015610c1d573d6000803e3d6000fd5b50505050600083511180610c3057503415155b15610c9e57610c3d611251565b6001600160a01b031663e4a833003487866040518463ffffffff1660e01b8152600401610c6b9291906128f1565b6000604051808303818588803b158015610c8457600080fd5b505af1158015610c98573d6000803e3d6000fd5b50505050505b815115610cb157610caf858361125c565b505b815115610d62576000610cc26111ca565b6001600160a01b031663f9a4cb1b876040518263ffffffff1660e01b8152600401610ced919061289b565b60206040518083038186803b158015610d0557600080fd5b505afa158015610d19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3d9190612597565b90506000811215610d605760405162461bcd60e51b815260040161058690612c03565b505b60405133906001600160a01b038716907f15258dcf35dab69581a17d65f7d1b639636265628d7ed1225dcac1081796c7b890600090a35050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b3360008181526035602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190610e22908590612b1e565b60405180910390a35050565b610e36610dae565b610e3f57600080fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b6036546001600160a01b031681565b6001600160a01b03918216600090815260356020908152604080832093909416825291909152205460ff1690565b6036546001600160a01b0316331480610ecf57506001600160a01b03861633148015610ecf5750610ecf8587610e70565b80610ef05750610edf8633610e70565b8015610ef05750610ef08533610e70565b610f0c5760405162461bcd60e51b815260040161058690612b7d565b6001600160801b03831115610f335760405162461bcd60e51b815260040161058690612b46565b60608115610f4a57610f47828401846124b1565b90505b6000610f55866111a5565b9050600080610f63886111ab565b9250509150610f7183611a71565b15611056578415610fe457610f84611251565b6001600160a01b031663e4a833008a866040518363ffffffff1660e01b8152600401610fb19291906128f1565b600060405180830381600087803b158015610fcb57600080fd5b505af1158015610fdf573d6000803e3d6000fd5b505050505b610fec6111ca565b6001600160a01b03166316745ae88a8c85858c6040518663ffffffff1660e01b815260040161101f9594939291906128af565b600060405180830381600087803b15801561103957600080fd5b505af115801561104d573d6000803e3d6000fd5b50505050611125565b61105f83611a8c565b1561110d5784156110d257611072611251565b6001600160a01b031663e4a833008b866040518363ffffffff1660e01b815260040161109f9291906128f1565b600060405180830381600087803b1580156110b957600080fd5b505af11580156110cd573d6000803e3d6000fd5b505050505b6110da6111ca565b6001600160a01b03166316745ae88b8b85858c6040518663ffffffff1660e01b815260040161101f9594939291906128af565b60405162461bcd60e51b815260040161058690612b62565b886001600160a01b03168a6001600160a01b0316336001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628b8b604051611174929190612c43565b60405180910390a450505050505050505050565b611190610dae565b61119957600080fd5b6111a281611abe565b50565b60f81b90565b603881901c60ff1691602882901c61ffff169160081c63ffffffff1690565b600060348160015b81526020810191909152604001600020546001600160a01b0316905090565b606081015160408201516020830151835160f81b6001600160f81b03191661ffff60e81b60e89290921b919091161763ffffffff60c81b60c89290921b919091161760ff60c01b60389290921c919091161760c01c919050565b303b1590565b6000603481806111d2565b606080825160405190808252806020026020018201604052801561129a57816020015b611287611dd3565b81526020019060019003908161127f5790505b50905060005b83518110156119d3576112b1611df5565b6112b96111ca565b6001600160a01b0316636dab47fd8684815181106112d357fe5b6020026020010151602001516040518263ffffffff1660e01b81526004016112fb9190612c51565b60a06040518083038186803b15801561131357600080fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061134b91906126fb565b6060810151909150600086848151811061136157fe5b602002602001015160000151600381111561137857fe5b141561152357600086848151811061138c57fe5b60200260200101516080015151602014156113d3578684815181106113ad57fe5b6020026020010151608001518060200190518101906113cc91906127aa565b90506113da565b5063ffffffff5b82608001518585815181106113eb57fe5b60200260200101516000019061ffff16908161ffff1681525050600085858151811061141357fe5b602002602001015160200190600381111561142a57fe5b9081600381111561143757fe5b81525050816001600160a01b0316630f6362568989878151811061145757fe5b6020026020010151604001518a888151811061146f57fe5b602002602001015160600151856040518563ffffffff1660e01b815260040161149b9493929190612aa2565b602060405180830381600087803b1580156114b557600080fd5b505af11580156114c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ed9190612776565b8585815181106114f957fe5b6020026020010151604001906001600160801b031690816001600160801b031681525050506119c9565b600186848151811061153157fe5b602002602001015160000151600381111561154857fe5b141561161c57600086848151811061155c57fe5b602002602001015160800151516020141561159f5786848151811061157d57fe5b60200260200101516080015180602001905181019061159c91906127aa565b90505b82608001518585815181106115b057fe5b60200260200101516000019061ffff16908161ffff168152505060018585815181106115d857fe5b60200260200101516020019060038111156115ef57fe5b908160038111156115fc57fe5b81525050816001600160a01b031663d6789ec08989878151811061145757fe5b600286848151811061162a57fe5b602002602001015160000151600381111561164157fe5b141561185c57600080600088868151811061165857fe5b60200260200101516080015151604014156116ac5788868151811061167957fe5b60200260200101516080015180602001905181019061169891906127c6565b90935091506001600160801b039050611715565b8886815181106116b857fe5b6020026020010151608001515160601415611704578886815181106116d957fe5b6020026020010151608001518060200190518101906116f891906127f4565b91945092509050611715565b5063ffffffff90506001600160801b035b846080015187878151811061172657fe5b60200260200101516000019061ffff16908161ffff1681525050600287878151811061174e57fe5b602002602001015160200190600381111561176557fe5b9081600381111561177257fe5b8152505088868151811061178257fe5b60200260200101516060015187878151811061179a57fe5b6020026020010151604001906001600160801b031690816001600160801b031681525050836001600160a01b03166389dd65b08b8b89815181106117da57fe5b6020026020010151604001518c8a815181106117f257fe5b6020026020010151606001518588886040518763ffffffff1660e01b815260040161182296959493929190612a5a565b600060405180830381600087803b15801561183c57600080fd5b505af1158015611850573d6000803e3d6000fd5b505050505050506119c9565b600386848151811061186a57fe5b602002602001015160000151600381111561188157fe5b14156119c957816080015184848151811061189857fe5b60200260200101516000019061ffff16908161ffff168152505060038484815181106118c057fe5b60200260200101516020019060038111156118d757fe5b908160038111156118e457fe5b81525050806001600160a01b0316634e9a6c308888868151811061190457fe5b60200260200101516040015189878151811061191c57fe5b6020026020010151606001516040518463ffffffff1660e01b815260040161194693929190612a2a565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612776565b8484815181106119a457fe5b6020026020010151604001906001600160801b031690816001600160801b0316815250505b50506001016112a0565b509392505050565b60005b8151811015611a6b578181815181106119f357fe5b6020026020010151604001516001600160801b031660001415611a6357611a32828281518110611a1f57fe5b6020026020010151602001518585611b2c565b828281518110611a3e57fe5b6020026020010151604001906001600160801b031690816001600160801b0316815250505b6001016119de565b50505050565b6000611a7c82611d11565b8015610781575061078182611d2f565b6000611a9782611d11565b8015611aa75750611aa782611d3b565b80156107815750611ab782611d47565b1592915050565b6001600160a01b038116611ad157600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008060005b8351811015611b89578561ffff16848281518110611b4c57fe5b60200260200101516000015161ffff161415611b8157838181518110611b6e57fe5b6020026020010151602001519150611b89565b600101611b32565b5060005b8451811015611d08578561ffff16858281518110611ba757fe5b60200260200101516000015161ffff1614611bc157611d00565b6000858281518110611bcf57fe5b6020026020010151602001516003811115611be657fe5b1480611c1457506003858281518110611bfb57fe5b6020026020010151602001516003811115611c1257fe5b145b15611c5357611c4c858281518110611c2857fe5b602002602001015160400151836001600160801b0316611d6690919063ffffffff16565b9150611d00565b6001858281518110611c6157fe5b6020026020010151602001516003811115611c7857fe5b1480611ca657506002858281518110611c8d57fe5b6020026020010151602001516003811115611ca457fe5b145b15611d0057848181518110611cb757fe5b6020026020010151604001516001600160801b0316826001600160801b031610611cfa57848181518110611ce757fe5b6020026020010151604001518203611cfd565b60005b91505b600101611b8d565b50949350505050565b6000600160fa1b8216158015610781575050600160fb1b9081161490565b600160fc1b9081161490565b600160fd1b9081161490565b6000600160fa1b828116148015610781575050600160fb1b9081161490565b60008282016001600160801b038085169082161015611d975760405162461bcd60e51b815260040161058690612b29565b9392505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040805160608101909152600080825260208201908152600060209091015290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b60008083601f840112611e34578182fd5b50813567ffffffffffffffff811115611e4b578182fd5b6020830191508360208083028501011115611e6557600080fd5b9250929050565b600082601f830112611e7c578081fd5b8135611e8f611e8a82612cba565b612c93565b8181529150602080830190848101604080850287018301881015611eb257600080fd5b60005b85811015611ed957611ec78984612051565b85529383019391810191600101611eb5565b50505050505092915050565b600082601f830112611ef5578081fd5b8135611f03611e8a82612cba565b818152915060208083019084810160005b84811015612006578135870160a080601f19838c03011215611f3557600080fd5b611f3e81612c93565b85830135611f4b81612d35565b8152604083810135611f5c81612d79565b82880152606084810135611f6f81612d67565b83830152608085810135611f8281612d42565b80838601525084860135915067ffffffffffffffff821115611fa357600080fd5b81860194508d603f860112611fb757600080fd5b888501359550611fc9611e8a87612cda565b91508582528d83878701011115611fdf57600080fd5b611fee868a8401858801612cfe565b83015250865250509282019290820190600101611f14565b505050505092915050565b60008083601f840112612022578182fd5b50813567ffffffffffffffff811115612039578182fd5b602083019150836020828501011115611e6557600080fd5b600060408284031215612062578081fd5b61206c6040612c93565b9050813561207981612d57565b8152602082013561208981612d42565b602082015292915050565b6000602082840312156120a5578081fd5b8135611d9781612d0a565b600080604083850312156120c2578081fd5b82356120cd81612d0a565b915060208301356120dd81612d0a565b809150509250929050565b60008060008060008060008060a0898b031215612103578384fd5b883561210e81612d0a565b9750602089013561211e81612d0a565b9650604089013567ffffffffffffffff8082111561213a578586fd5b6121468c838d01611e23565b909850965060608b013591508082111561215e578586fd5b61216a8c838d01611e23565b909650945060808b0135915080821115612182578384fd5b5061218f8b828c01612011565b999c989b5096995094979396929594505050565b60008060008060008060a087890312156121bb578384fd5b86356121c681612d0a565b955060208701356121d681612d0a565b94506040870135935060608701359250608087013567ffffffffffffffff8111156121ff578283fd5b61220b89828a01612011565b979a9699509497509295939492505050565b6000806040838503121561222f578182fd5b823561223a81612d0a565b9150602083013580151581146120dd578182fd5b60008060408385031215612260578182fd5b823561226b81612d0a565b946020939093013593505050565b6000806000806080858703121561228e578182fd5b843561229981612d0a565b935060208501356122a981612d67565b9250604085013567ffffffffffffffff808211156122c5578384fd5b6122d188838901611e6c565b935060608701359150808211156122e6578283fd5b506122f387828801611ee5565b91505092959194509250565b600080600080600060a08688031215612316578283fd5b853561232181612d0a565b945060208681013561233281612d67565b9450604087013567ffffffffffffffff8082111561234e578586fd5b61235a8a838b01611e6c565b9550606091508189013581811115612370578485fd5b61237c8b828c01611ee5565b955050608089013581811115612390578485fd5b89019050601f81018a136123a2578384fd5b80356123b0611e8a82612cba565b81815284810190838601858402850187018e10156123cc578788fd5b8794505b838510156124345785818f0312156123e6578788fd5b6123ef86612c93565b81356123fa81612d0a565b81528188013561240981612d57565b81890152604082013561241b81612d42565b60408201528352600194909401939186019185016123d0565b508096505050505050509295509295909350565b6000806000806040858703121561245d578182fd5b843567ffffffffffffffff80821115612474578384fd5b61248088838901611e23565b90965094506020870135915080821115612498578384fd5b506124a587828801611e23565b95989497509550505050565b600060208083850312156124c3578182fd5b823567ffffffffffffffff8111156124d9578283fd5b80840185601f8201126124ea578384fd5b803591506124fa611e8a83612cba565b828152838101908285016040808602850187018a1015612518578788fd5b8794505b858510156125445761252e8a83612051565b845260019490940193928601929081019061251c565b509098975050505050505050565b600060208284031215612563578081fd5b81356001600160e01b031981168114611d97578182fd5b6000806040838503121561258c578182fd5b82356120cd81612d35565b6000602082840312156125a8578081fd5b5051919050565b600060c082840312156125c0578081fd5b50919050565b600060c082840312156125d7578081fd5b6125e160c0612c93565b82356125ec81612d79565b815260208301356125fc81612d57565b6020820152604083013561260f81612d67565b6040820152606083013561262281612d1f565b6060820152608083013561263581612d67565b608082015260a083013561264881612d42565b60a08201529392505050565b60008082840360e0811215612667578283fd5b60c0811215612674578283fd5b5061267f60c0612c93565b835161268a81612d79565b8152602084015161269a81612d57565b602082015260408401516126ad81612d67565b604082015260608401516126c081612d1f565b606082015260808401516126d381612d67565b608082015260a08401516126e681612d42565b60a082015260c0939093015192949293505050565b600060a0828403121561270c578081fd5b61271660a0612c93565b825161272181612d67565b8152602083015161273181612d67565b6020820152604083015161274481612d67565b6040820152606083015161275781612d0a565b6060820152608083015161276a81612d57565b60808201529392505050565b600060208284031215612787578081fd5b8151611d9781612d42565b6000602082840312156127a3578081fd5b5035919050565b6000602082840312156127bb578081fd5b8151611d9781612d67565b600080604083850312156127d8578182fd5b82516127e381612d67565b60208401519092506120dd81612d67565b600080600060608486031215612808578081fd5b835161281381612d67565b602085015190935061282481612d67565b604085015190925061283581612d42565b809150509250925092565b60008060008060808587031215612855578182fd5b843561286081612d79565b9350602085013561287081612d57565b9250604085013561288081612d67565b9150606085013561289081612d1f565b939692955090935050565b6001600160a01b0391909116815260200190565b6001600160a01b03958616815293909416602084015260ff91909116604083015263ffffffff1660608201526001600160801b03909116608082015260a00190565b6001600160a01b038316815260406020808301829052835183830181905260009291858101916060860190855b81811015612544578451805161ffff1684528401516001600160801b031684840152938301939185019160010161291e565b6001600160a01b038381168252604060208084018290528451848301819052600093606092909183870190888301875b828110156129bc5781518051871685528581015161ffff16868601528801516001600160801b0316888501529286019290840190600101612980565b50919a9950505050505050505050565b6001600160a01b039590951685526001600160f81b031993909316602085015260ff91909116604084015261ffff16606083015263ffffffff16608082015260a00190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393909316835263ffffffff9190911660208301526001600160801b0316604082015260600190565b6001600160a01b0396909616865263ffffffff94851660208701526001600160801b03938416604087015291909216606085015290821660808401521660a082015260c00190565b6001600160a01b0394909416845263ffffffff92831660208501526001600160801b0391909116604084015216606082015260800190565b6020808252825182820181905260009190848201906040850190845b81811015612b1257835183529284019291840191600101612af6565b50909695505050505050565b901515815260200190565b6020808252600390820152620c4c0d60ea1b604082015260600190565b6020808252600290820152610d0d60f21b604082015260600190565b6020808252600190820152603760f81b604082015260600190565b602080825260029082015261032360f41b604082015260600190565b602080825260029082015261062760f31b604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201526d195b881a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252600190820152603560f81b604082015260600190565b602080825260029082015261191960f11b604082015260600190565b90815260200190565b918252602082015260400190565b60ff91909116815260200190565b60ff94909416845261ffff92909216602084015263ffffffff1660408301526001600160f81b031916606082015260800190565b60405181810167ffffffffffffffff81118282101715612cb257600080fd5b604052919050565b600067ffffffffffffffff821115612cd0578081fd5b5060209081020190565b600067ffffffffffffffff821115612cf0578081fd5b50601f01601f191660200190565b82818337506000910152565b6001600160a01b03811681146111a257600080fd5b6001600160f81b0319811681146111a257600080fd5b600481106111a257600080fd5b6001600160801b03811681146111a257600080fd5b61ffff811681146111a257600080fd5b63ffffffff811681146111a257600080fd5b60ff811681146111a257600080fdfea2646970667358221220fa9cd7e8d6a94076927516b2b2da6d02764b07646eadf3f41b46ff41fe6c059d64736f6c63430006040033",
"linkReferences": {},
"deployedLinkReferences": {}
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
{
"DAI": "0x181D62Ff8C0aEeD5Bc2Bf77A88C07235c4cc6905",
"USDC": "0xF503D5cd87d10Ce8172F9e77f76ADE8109037b4c",
"WBTC": "0x45a8451ceaae5976b4ae5f14a7ad789fae8e9971",
"WETH": "0xd0a1e359811322d97991e03f863a0c30c2cf029c",
"cDAI": "0x4dC87A3D30C4A1B33E4349f02F4c5B1B1eF9A75D",
"cETH": "0x40575f9Eb401f63f66F4c434248ad83D3441bf61",
"cUSDC": "0xf17C5c7240CBc83D3186A9d6935F003e451C5cDd",
"cWBTC": "0xA8E51e20985E926dE882EE700eC7F7d51D89D130",
"cashMarketLogic": "0x346944E951038Db475F347849Ad6e3967181E3F2",
"chainId": 42,
"compAdmin": "0x010c90d15D62E5F07a3AF28EbB99DEaaaD645f97",
"compPriceOracle": "0x9D13E1A715149abcF12fD538C1Cd48F2E8C6899C",
"comptroller": "0x2D5D30a561278a5F0ad8779A386dAA4C478865D0",
"directory": "0xdce848258dFB1bBf34C346Fbe40F10F8a42d2526",
"erc1155": "0x3a31b8121D810B1D7b3004f94f205E6DFC1bf8d9",
"erc1155trade": "0xBbA899578bd3fA3DAa863A340f5600797993eF08",
"escrow": "0x9abd0b8868546105F6F48298eaDC1D9c82f7f683",
"libraries": {
"Liquidation": "0xeD176679A42c5F0b3602c3Df705577b92646345a",
"RiskFramework": "0xc20846f8d295C354f9EcB48a695d41D785C35e07"
},
"networkName": "kovan",
"portfolios": "0x0A4721117040ABF319b954aBF13F654505C34920",
"proxyAdmin": "0x25d27646Ea585Ee7Ef308d14f4C0D2b094790Acb",
"proxyFactory": "0xc981D9E52684A25e528ba63552dF122Af8327D4E",
"startBlock": 21065054,
"wETHwBTCUniswapV2": "0x1D925AA3d6fEf028FB607d5E8250C1A5AC8E0D99"
}
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.7.0;
pragma experimental ABIEncoderV2;
// WARNING: this is unaudited code. Use at your own risk. Very much recommended that this
// should be deployed behind an upgradeable proxy in case of issues.
// WARNING: Compound borrow will be credited to this contract and therefore this contract must hold your cTokens, not
// your wallet. This increases the risk of your collateral becoming locked or lost. PROCEED WITH CAUTION.
// Uses this release of OZ contracts: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v3.4-solc-0.7
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface WETH9 {
function withdraw(uint256 wad) external;
function transfer(address dst, uint256 wad) external returns (bool);
}
interface IEscrow {
function getBalances(address account) external view returns (int256[] memory);
function currencyIdToAddress(uint16 currencyId) external view returns (address);
}
interface UniswapPair {
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
}
interface INotionalV1Erc1155 {
/** Notional V1 Types */
struct Deposit {
// Currency Id to deposit
uint16 currencyId;
// Amount of tokens to deposit
uint128 amount;
}
/**
* Used to describe withdraws in ERC1155.batchOperationWithdraw
*/
struct Withdraw {
// Destination of the address to withdraw to
address to;
// Currency Id to withdraw
uint16 currencyId;
// Amount of tokens to withdraw
uint128 amount;
}
enum TradeType {
TakeCurrentCash,
TakefCash,
AddLiquidity,
RemoveLiquidity
}
/**
* Used to describe a trade in ERC1155.batchOperation
*/
struct Trade {
TradeType tradeType;
uint8 cashGroup;
uint32 maturity;
uint128 amount;
bytes slippageData;
}
function batchOperationWithdraw(
address account,
uint32 maxTime,
Deposit[] memory deposits,
Trade[] memory trades,
Withdraw[] memory withdraws
) external payable;
}
interface CEtherInterface {
function mint() external payable;
function borrow(uint256 borrowAmount) external returns (uint256);
}
interface CErc20Interface {
function mint(uint256 mintAmount) external returns (uint256);
function borrow(uint256 borrowAmount) external returns (uint256);
}
interface ComptrollerInterface {
function enterMarkets(address[] calldata cTokens) external returns (uint256[] memory);
}
contract NotionalV1ToCompound {
address public owner;
IEscrow public immutable Escrow;
INotionalV1Erc1155 public immutable NotionalV1Erc1155;
UniswapPair public immutable wETHwBTCPair;
WETH9 public immutable WETH;
IERC20 public immutable WBTC;
address public immutable Comptroller;
address public immutable cETH;
address public immutable cDAI;
address public immutable cUSDC;
address public immutable cWBTC;
uint16 internal constant V1_ETH = 0;
uint16 internal constant V1_DAI = 1;
uint16 internal constant V1_USDC = 2;
uint16 internal constant V1_WBTC = 3;
function initialize() external {
owner = msg.sender;
}
/// @dev Throws if called by any account other than the owner.
modifier onlyOwner() {
require(owner == msg.sender, "Ownable: caller is not the owner");
_;
}
/// @dev Transfers ownership of the contract to a new account (`newOwner`).
/// Can only be called by the current owner.
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
owner = newOwner;
}
constructor(
IEscrow escrow_,
INotionalV1Erc1155 erc1155_,
UniswapPair wETHwBTCPair_,
WETH9 weth_,
IERC20 wbtc_,
address comptroller_,
address cETH_,
address cDAI_,
address cUSDC_,
address cWBTC_
) {
Escrow = escrow_;
NotionalV1Erc1155 = erc1155_;
Comptroller = comptroller_;
wETHwBTCPair = wETHwBTCPair_;
WETH = weth_;
WBTC = wbtc_;
cETH = cETH_;
cDAI = cDAI_;
cUSDC = cUSDC_;
cWBTC = cWBTC_;
}
function migrateDaiEther(uint128 v1RepayAmount) external onlyOwner {
_flashBorrowCollateral(V1_DAI, cDAI, V1_ETH, cETH, v1RepayAmount);
}
function migrateUSDCEther(uint128 v1RepayAmount) external onlyOwner {
_flashBorrowCollateral(V1_USDC, cUSDC, V1_ETH, cETH, v1RepayAmount);
}
function migrateDaiWBTC(uint128 v1RepayAmount) external onlyOwner {
_flashBorrowCollateral(V1_DAI, cDAI, V1_WBTC, cWBTC, v1RepayAmount);
}
function migrateUSDCWBTC(uint128 v1RepayAmount) external onlyOwner {
_flashBorrowCollateral(V1_USDC, cUSDC, V1_WBTC, cWBTC, v1RepayAmount);
}
/** Use this to approve a spender for the cToken allowance */
function approveAllowance(
address token,
address spender,
uint256 allowance
) external onlyOwner {
IERC20(token).approve(spender, allowance);
}
function _flashBorrowCollateral(
uint16 v1DebtCurrencyId,
address cTokenBorrowAddress,
uint16 v1CollateralId,
address cTokenCollateralAddress,
uint128 v1RepayAmount
) internal returns (uint256) {
int256[] memory balances = Escrow.getBalances(msg.sender);
int256 collateralBalance = (
v1CollateralId == V1_ETH ? balances[V1_ETH] : balances[V1_WBTC]
);
require(collateralBalance > 0);
bytes memory encodedData = abi.encode(
msg.sender,
v1DebtCurrencyId,
cTokenBorrowAddress,
v1CollateralId,
cTokenCollateralAddress,
v1RepayAmount,
uint256(collateralBalance)
);
uint256 swapAmount = (uint256(collateralBalance) * 996) / 1000;
if (v1CollateralId == V1_WBTC) {
wETHwBTCPair.swap(swapAmount, 0, address(this), encodedData);
} else if (v1CollateralId == V1_ETH) {
wETHwBTCPair.swap(0, swapAmount, address(this), encodedData);
}
}
function _repayFlashBorrow(uint256 v1CollateralId, uint256 amount) internal {
bool success;
if (v1CollateralId == V1_ETH) {
success = WETH.transfer(msg.sender, amount);
} else if (v1CollateralId == V1_WBTC) {
success = WBTC.transfer(msg.sender, amount);
}
require(success);
}
function uniswapV2Call(
address sender,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external {
// Flash swap call must come from this contract
require(sender == address(this), "sender mismatch");
// decode message
(
address migrator,
uint16 v1DebtCurrencyId,
address cTokenBorrowAddress,
uint16 v1CollateralId,
address cTokenCollateral,
uint128 v1RepayAmount,
uint256 collateralAmount
) = abi.decode(data, (address, uint16, address, uint16, address, uint128, uint256));
// transfer tokens to original caller
uint256 swapAmount;
if (v1CollateralId == V1_WBTC) {
swapAmount = amount0;
} else if (v1CollateralId == V1_ETH) {
swapAmount = amount1;
WETH.withdraw(amount1);
}
_migrate(
migrator,
v1DebtCurrencyId,
cTokenBorrowAddress,
v1CollateralId,
cTokenCollateral,
v1RepayAmount,
collateralAmount,
swapAmount
);
_repayFlashBorrow(v1CollateralId, collateralAmount);
}
function _migrate(
address migrator,
uint16 v1DebtCurrencyId,
address cTokenBorrowAddress,
uint16 v1CollateralId,
address cTokenCollateralAddress,
uint128 v1RepayAmount,
uint256 collateralAmount,
uint256 swapAmount
) internal {
// Mints cToken collateral from underlying that was flash borrowed
if (cTokenCollateralAddress == address(cETH)) {
CEtherInterface(cTokenCollateralAddress).mint{value: swapAmount}();
} else {
CErc20Interface(cTokenCollateralAddress).mint(swapAmount);
}
address[] memory markets = new address[](2);
markets[0] = cTokenCollateralAddress;
markets[1] = cTokenBorrowAddress;
uint256[] memory returnCodes = ComptrollerInterface(Comptroller).enterMarkets(markets);
require(returnCodes[0] == 0 && returnCodes[1] == 0, "Enter markets failed");
// Borrows v1RepayAmount from Compound and will be sent to this contract's address
// Debt will be credited to this contract address.
CErc20Interface(cTokenBorrowAddress).borrow(v1RepayAmount);
address debtCurrencyAddress = Escrow.currencyIdToAddress(v1DebtCurrencyId);
// Transfer the borrowed assets to the migrator to repay the loan on Notional V1
IERC20(debtCurrencyAddress).transfer(migrator, v1RepayAmount);
{
INotionalV1Erc1155.Deposit[] memory deposits = new INotionalV1Erc1155.Deposit[](1);
INotionalV1Erc1155.Trade[] memory trades = new INotionalV1Erc1155.Trade[](0);
INotionalV1Erc1155.Withdraw[] memory withdraws = new INotionalV1Erc1155.Withdraw[](1);
// This will deposit what we borrowed from Compound
deposits[0].currencyId = v1DebtCurrencyId;
deposits[0].amount = v1RepayAmount;
// This will withdraw to the current contract the collateral to repay the flash loan
withdraws[0].currencyId = v1CollateralId;
withdraws[0].to = address(this);
withdraws[0].amount = uint128(collateralAmount);
NotionalV1Erc1155.batchOperationWithdraw(
migrator,
uint32(block.timestamp),
deposits,
trades,
withdraws
);
}
}
receive() external payable {}
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _value,
bytes calldata _data
) external returns (bytes4) {
return 0xf23a6e61;
}
}
def test_migrate_v1_to_comp(environment, accounts, NotionalV1ToCompound):
account = accounts[3]
(v1env, v2env) = environment
v1ToComp = NotionalV1ToCompound.deploy(
v1env["Escrow"].address,
v1env["ERC1155Trade"].address,
v1env["uniswapFactory"].getPair(v1env["WETH"].address, v2env.token["WBTC"]),
v1env["WETH"].address,
v2env.token["WBTC"],
v2env.comptroller.address,
v2env.cToken["ETH"],
v2env.cToken["DAI"],
v2env.cToken["USDC"],
v2env.cToken["WBTC"],
{"from": accounts[3]},
)
# USDC w/ ETH
erc1155 = Contract.from_abi(
"ERC1155Trade", address=v1env["ERC1155Trade"].address, abi=v1env["ERC1155Trade"].abi
)
erc1155.setApprovalForAll(v1ToComp.address, True, {"from": account})
v2env.token["USDC"].approve(v1env["Escrow"].address, 2 ** 255, {"from": account})
v1ToComp.migrateUSDCEther(100e6)
balances = v1env["Escrow"].functions.getBalances(account.address).call()
assert balances[0] == 0
assert balances[1] == 0
assert balances[2] == 100e6
assert balances[3] == 0
assert (v2env.cToken["USDC"].borrowBalanceCurrent(v1ToComp.address)).return_value > 0
with brownie.reverts():
v1ToComp.approveAllowance(v2env.cToken["ETH"], accounts[1], 100e8, {"from": accounts[1]})
v1ToComp.approveAllowance(v2env.cToken["ETH"], accounts[3], 2 ** 255, {"from": accounts[3]})
balanceBefore = v2env.cToken["ETH"].balanceOf(accounts[3])
v2env.cToken["ETH"].transferFrom(v1ToComp.address, accounts[3], 10, {"from": accounts[3]})
balanceAfter = v2env.cToken["ETH"].balanceOf(accounts[3])
assert balanceBefore + 10 == balanceAfter
# Cannot transfer if not approved
balanceBefore = v2env.cToken["ETH"].balanceOf(accounts[1])
# This does not revert outright...
v2env.cToken["ETH"].transferFrom(v1ToComp.address, accounts[1], 10, {"from": accounts[1]})
balanceAfter = v2env.cToken["ETH"].balanceOf(accounts[1])
assert balanceBefore == balanceAfter
# Assert we can repay and withdraw collateral
v2env.cToken["USDC"].repayBorrowBehalf(v1ToComp.address, 100e6, {"from": accounts[0]})
v2env.cToken["ETH"].transferFrom(
v1ToComp.address,
accounts[3],
v2env.cToken["ETH"].balanceOf(v1ToComp.address),
{"from": accounts[3]},
)
assert v2env.cToken["ETH"].balanceOf(v1ToComp.address) == 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment